Un novo enxeñeiro PHP

PHP No Comments »

Acabo de aprobar o exame de certificación de Zend en PHP5 (ou como dín eles, PASS THE EXAM, porque o exame é en inglés).

O exame consistía nun test de 70 preguntas acerca de PHP e de todas as tecnoloxías relacionadas (MySQL, XML, Soap, Patróns, …) a contestar en 90 minutos (sobroume algún, pero non moitos). As preguntas podían ter respostas multiples, ou ter que encher un oco co nome da función ou da directiva relacionada. O exame foi moito máis difícil do que esperaba, que xa era dabondo, e foron poucas as preguntas, que lidas e de primeiras era quen de coñecer a súa resposta con seguridade.

A utilidade, pois era máis ben un reto persoal, pois aparte de poder poñelo no meu currículo, empregar o logo para poñelo neste blog ou na firma dalgún correo, e aparecer no listado das páxinas amarelas de Zend (a empresa fabricante do PHP) de posuidores do certificado (só 26 en España, e só 5 no que vai de ano, o que xa da idea do sinxelo que é conseguilo) , para pouco máis me vai servir. Minto, para decatarme do moito que me queda por aprender de PHP, terei que seguir aprendendo.

Listado de posuidores en España da certificación Zend PHP5 Certified Engineer

Acreditación persoal como Zend PHP5 Certified Engineer

Zend PHP5 Certified Engineer

Ler o contido dun ficheiro

PHP No Comments »

Hai unha chea de método para ler o contido dun ficheiro, xa aberto para lectura:

$id = fopen("ficheiro.txt","r");

while (!feof($id))
	echo fgets($id)."<br />";

echo ftell($id)."<br />";
fseek($id,0);
while (!feof($id))
	echo fread($id,2);		

echo ftell($id)."<br />";
rewind($id);
while (($letra = fgetc($id)) !== FALSE)
	echo $letra;	

$liñas = file("ficheiro.txt");
foreach ($liñas as $liña)
	echo $liña . "<br />";		

readfile("ficheiro.txt");

echo file_get_contents("ficheiro.txt");
fclose($id);
  • fgetc: Obtén un carácter dende a posición actual do punteiro, e móveo un byte cara adiante
  • fgets: Obtén unha cadea dende a posición actual do punteiro ata o seguinte salto de liña atopado, e move o punteiro ata o seguinte byte ao salto de liña
  • fgetss: Igual que a anterior pero elimina da cadea todas as etiquetas HTML e código PHP
  • fread: Obtén unha cadea dende a posición actual do punteiro ata o número de bytes indicados ou o final do ficheiro, e move o punteiro ata o seguinte byte ao último devolto
  • file: Devolve un array que contén en cada elemento unha liña do ficheiro indicado. Esta función recibe como primeiro parámetro o nome do ficheiro e non o identificador deste, polo que non é necesarioabrir o ficheiro con fopen antes de empregar esta función.
  • readfile: Envia a saída estandar (navegador) o contido do ficheiro. Esta función recibe como primeiro parámetro o nome do ficheiro.
  • file_get_contents: Devolve un string que contén o contido do ficheiro. Esta función recibe como primeiro parámetro o nome do ficheiro.
  • Para movernos polo ficheiros dispoñemos das seguintes funcións:

  • ftell(): Indícanos en que byte está posicionados o punteiro
  • fseek(): Posiciona o punteiro no byte indicado
  • rewind(): Posiciona o punteiro no byte 0
  • feof(): Devolve True cando o punteiro alcanza o final do ficheiro
  • Ollos cos modos de apertura dun arquivo

    PHP No Comments »

    En PHP podemos acceder os ficheiros situados no ordenador que ten o servidor web. Para elo, normalmente, o primeiro que teremos que facer é abrir o arquivo coa función fopen indicando o nome do ficheiro e o modo no que abrimos ese ficheiro. Os modos dispoñibles son os seguintes:

    $id = fopen("ficheiro.txt","r+");
    
  • r: O ficheiro ábrese para ler, situando o punteiro de lectura ao comezo do ficheiro. Se o ficheiro non existe prodúcese un warning (e evidentemente non se crea o ficheiro).
  • r+: O ficheiro ábrese para ler e escribir, situando o punteiro de lectura/escritura ao comezo do ficheiro. Se o ficheiro non existe prodúcese un warning (e evidentemente non se crea o ficheiro).
  • w: O ficheiro ábrese para escribir, situando o punteiro de escritura ao comezo do ficheiro. Se o ficheiro non existe crease un novo baleiro, e se existe truncase o seu tamaño a cero (e dicir, baleirase, ou visto doutro xeito, é como se se borrase e se volvese a crear baleiro). Polo tanto os datos que haxa no seu interior pérdense.
  • w+: O ficheiro ábrese para escribir e ler, situando o punteiro de escritura/lectura ao comezo do ficheiro. Se o ficheiro non existe crease un novo baleiro, e se existe truncase o seu tamaño a cero (e dicir, baleirase, ou visto doutro xeito, é como se se borrase e se volvese a crear baleiro). Polo tanto os datos que haxa no seu interior pérdense.
  • a: O ficheiro ábrese para engadir (escribir), situando o punteiro de escritura ao final do ficheiro. Se o ficheiro non existe crease un novo baleiro.
  • a+: O ficheiro ábrese para engadir (escribir) e ler, situando o punteiro de escritura/lectura ao final do ficheiro. Se o ficheiro non existe crease un novo baleiro.
  • x: O ficheiro ábrese para escribir, situando o punteiro de escritura ao comezo do ficheiro. Se o ficheiro existe prodúcese un warning. E dicir, para empregar este modo o ficheiro non debe existir, e crease un novo e situase o punteiro de escritura ao seu comezo.
  • x+: O ficheiro ábrese para escribir e ler, situando o punteiro de escritura/lectura ao comezo do ficheiro. Se o ficheiro existe prodúcese un warning. E dicir, para empregar este modo o ficheiro non debe existir, e crease un novo e situase o punteiro de escritura/lectura ao seu comezo.
  • Buscando nun XML con XPath

    PHP No Comments »

    SimpleXMLElement tamén permite facer busquedas dentro dun XML empregando XPath, unha linguaxe de recorrido de XML. Para elo dispoñemos do método SimpleXMLElement->xpath(ruta), que devolve un array cos elementos atopados. A ruta indica que elementos estamos a buscar, e segue a sintase da linguaxe XPath.

    Un tutorial bastante sinxelo de iniciación a XPath, que nos pode axudar a entender como buscar dentro do XML empregando esta linguaxe: http://sherekan.com.ar/2008/09/16/introduccion-a-xpath/

    $libraria = new SimpleXMLElement('ficheiro.xml',NULL,true);
    
    // Obter todos os nodos editor
    $listado = $libraria->xpath('//editor');
    foreach($listado as $ele)
    	echo $ele ."<br />";
    
    // Obter od nodos editor situados dentro dun nodo libro situado
    // a sua vez no nodo raíz libraria
    $listado = $libraria->xpath('/libraria/libro/editor');
    foreach($listado as $ele)
    	echo $ele ."<br />";
    
    // Obter todos os atributos isbn
    $listado = $libraria->xpath('//@isbn');
    foreach($listado as $ele)
    	echo $ele ."<br />";
    

    Como engadir un nodo a un XML

    PHP No Comments »

    Seguindo co uso da clase SimpleXML (http://es.php.net/manual/es/book.simplexml.php) tamén se pode engadir de xeito sinxelo un novo nodo a un XML. Para isto temos que crear un obxeto da clase SimpleXMLElement, inicializándoo ben cun String que conteña o XML (new SimpleXMLElement(string) ) ou ben co nome do ficheiro que conteña o XML ( new SimpleXMLElement(ficheiro,NULL,True) ). Tamén dispoñemos de dúas funcións que obteñen o mesmo obxeto (simplexml_load_string(string) e simplexml_load_file(ficheiroXML)).

    Unha vez obtido o obxeto SimpleXMLElement, podemos acceder o nome de cada nodo, os seus atributos e os seus sobnodos cos métodos do obxeto (e con estes métodos situarnos no nodo onde queremos engadir o novo subnodo):

  • SimpleXMLElement->getName() para obter o nome do nodo
  • SimpleXMLElement->attributes() para obter un array cos atributos do nodo
  • SimpleXMLElement->children() para obter un array cos subnodos dun nodo dado
  • E engadir un novo nodo unha vez que estemos situado no punto axeitado do XML:

  • SimpleXMLElement->addChild(nome_nodo,valor_nodo) : Engade un novo nodo no punto indicado. Dito nodo terá unha etiqueta cuxo nome será o indicado no primeiro parámetro e se se indica segundo parámetro, ese será o valor do nodo.
  • SimpleXMLElement->addAttribute(nome_atributo,valor_atributo) : Engadelle o nodo actual un atributo co nome indicado no primeiro parámetro e o valor indicado no segundo.
  • Un exemplo de como engadir un nodo a un ficheiro XML e velo no navegador:

    $libraria = new SimpleXMLElement('ficheiro.xml',NULL,true);
    
    $novo_nodo = $libraria->addChild("libro");
    $novo_nodo->addAttribute('isbn','0812550706');
    $novo_nodo->addChild('titulo','Novo libro');
    $novo_nodo->addChild('autor','Novo autor');
    $novo_nodo->addChild('editor','Novo editor');
    
    echo $novo_nodo->asXML();
    

    Como percorrer un XML

    PHP No Comments »

    Facendo uso da clase SimpleXML (http://es.php.net/manual/es/book.simplexml.php) pódese percorrer de forma sinxela un XML. Para isto temos que crear un obxeto da clase SimpleXMLElement, inicializándoo ben cun String que conteña o XML (new SimpleXMLElement(string) ) ou ben co nome do ficheiro que conteña o XML ( new SimpleXMLElement(ficheiro,NULL,True) ). Tamén dispoñemos de dúas funcións que obteñen o mesmo obxeto (simplexml_load_string(string) e simplexml_load_file(ficheiroXML)).

    Unha vez obtido o obxeto SimpleXMLElement, podemos acceder o nome de cada nodo, os seus atributos e os seus sobnodos cos métodos do obxeto:

  • SimpleXMLElement->getName() para obter o nome do nodo
  • SimpleXMLElement->attributes() para obter un array cos atributos do nodo
  • SimpleXMLElement->children() para obter un array cos subnodos dun nodo dado
  • Se temos o seguinte XML:

    <?xml version="1.0" ?>
    <libraria>
    	<libro isbn="0345342968">
    		<titulo>Fahrenheit 451</titulo>
    		<autor>R. Brandbury</autor>
    		<editor>Del Rey</editor>
    	</libro>
    	<libro isbn="0048231398">
    		<titulo>The Silmarillion</titulo>
    		<autor>J.R.R. Tolkien</autor>
    		<editor>G. Allen and Unwin</editor>
    	</libro>
    	<libro isbn="0451524934">
    		<titulo>1984</titulo>
    		<autor>G. Orwell</autor>
    		<editor>Signet</editor>
    	</libro>
    	<libro isbn="031219126X">
    		<titulo>Frankenstein</titulo>
    		<autor>M. Shelley</autor>
    		<editor>Bedford</editor>
    	</libro>
    	<libro isbn="0312863551">
    		<titulo>The Moon Is a Harsh Mistress</titulo>
    		<autor>R. A. Heinlein</autor>
    		<editor>Orb</editor>
    	</libro>
    </libraria>
    

    Podemos percorrelo facendo uso dos obxetos e métodos vistos anteriormente:

    $libraria = new SimpleXMLElement('ficheiro.xml',NULL,true);
    procesar_Nodo($libraria);
    
    function procesar_Nodo($nodo) {
    	echo "<b>NODO :</b>".$nodo->getName() . "<br />";
    	// SE TEN ATRIBUTOS
    
    	if (count($nodo->attributes()) > 0) {
    		echo "<b>atributos :</b><br />";
    		foreach ($nodo->attributes() as $atributo) {
    			echo "  --<b>".$atributo->getName() ."</b>: ". $atributo . "<br />";
    		}
    	}
    
    	// SE NON TEN FILLOS IMPRIMESE O CONTIDO
    	if (count($nodo->children()) == 0) {
    		echo $nodo . "<br />";
    	}
    	foreach($nodo->children() as $subnodo) {
    		procesar_Nodo($subnodo);
    	}
    }
    

    O patrón Registry (rexistro)

    PHP No Comments »

    Ao emprego do patrón Registry ven a solucionar o problema de ter que pasar a obxetos ou funcións da nosa aplicación unha chea de parámetros ou ter que empregar variables globais. Consiste en crear un obxeto que conten un array asociativo onde se van gardando os valores que se desexe xunto co seu nome, de forma que serán accesibles posteriormente con so coñecer o nome da variable á que se desexa acceder.

    Asi en lugares de pasarlle as función, métodos ou constructores de obxetos unha chea de parámetros, pasaselle só un, o obxeto Registry.

    class patronRegistry {
        private static $_cache = array();
    
        public static function set($indice, &$valor) {
            self::$_cache[$indice] = $valor;
        }
        public static function &get($indice) {
            return self::$_cache[$indice];
        }
        public static function existe($indice) {
            return (self::get($indice) !== null);
        }
    }
    
    $obxeto1 = accesoDB::getAcceso();
    patronRegistry::set("accesoDB",$obxeto1);
    var_dump($obxeto1->getIdConexion());
    $obxeto2 = accesoDB::getAcceso();
    var_dump($obxeto2->getIdConexion());
    if (patronRegistry::existe("accesoDB")) {
      $obxeto3 = patronRegistry::get("accesoDB");
      var_dump($obxeto3->getIdConexion());
    }
    

    O patrón Singleton (instancia única)

    PHP No Comments »

    Os patróns de programación son técnicas ben coñecidas e probadas para resolver determinados problemas de programación.

    Un dos patróns é o Patrón Singletón que serve para acceder a recursos (ficheiros, conexións a base de datos) onde so se pode crear unha única instancia dese acceso (so unha conexión a BD, …). Para evitar que se creen varios accesos a dito recurso empregase as técnicas índicadas neste patrón..

    As técnicas que recolle este patrón para resolver dito problema son:

  • A visibiliade do constructor é privada, co que non é instanciable esta clase directamente, e así evitase que se vain creando varios accesos ao recurso (varias instancias do obxeto de acceso ao recurso)
  • Dispón dun método público e estático (método de clase) para obter o acceso ao recurso, método ao que se chamará cada vez que se quere obter un acceso a ese recurso
  • Dentro dese método, e empregando unha propiedade estática (de clase), comprobarase se xa se creou unha instancia do obxeto de acceso (que estará gardada se así foi nesa propiedade estática). Se non se creou, crease e gardase nesa propiedade; e en calquera caso devolvese o gardado nese propiedad (é dicir, se non se creou un obxeto de acceso, crease, e se non devolvese o existente, co que se evita crear varias instancias)
  • A súa implementación en PHP5 é a seguinte:

    class PatronSingleton
    {
        // Contenedor Instancia da Clase
        private static $instancia;
    
        // O constructor non é accesible
        private function __construct()
        {
            echo 'Son o constructor';
        }
    
        // O metodo accesible
        public static function singleton()
        {
            if (!isset(self::$instancia)) {
                $c = __CLASS__;
                self::$instancia = new $c;
            }
            return self::$instancia;
        }
    }
    
    $obxeto1 = PatronSingleton::singleton();
    $obxeto2 = PatronSingleton::singleton();
    

    Por exemplo, para realizar a conexión a un servidor de BD MySQL empregando este patrón de diseño:

    class accesoDB
    {
        // Contenedor Instancia da Clase
        private static $instancia;
        private $id_conexion;	
    
        // O constructor non é accesible
        private function __construct()
        {
            $this->id_conexion = mysql_connect("localhost","usuario","contrasinal");
        }
    
        // O metodo accesible
        public static function getAcceso()
        {
            if (!isset(self::$instancia)) {
                $c = __CLASS__;
                self::$instancia = new $c;
            }
    
            return self::$instancia;
        }
    
        public function getIdConexion() {
            return $this->id_conexion;
        }
    }
    
    $obxeto1 = accesoDB::getAcceso();
    var_dump($obxeto1->getIdConexion());
    $obxeto2 = accesoDB::getAcceso();
    var_dump($obxeto2->getIdConexion());
    

    Como se pode ver, devolvese sempre o mesmo identificador de recurso de conexión a BD, independentemente das veces que se emprege.

    POO: Olvideime de incluir unha clase, autocarga

    PHP No Comments »

    Antes de empregar unha clase (para instanciar un obxeto), a clase ten que estar definida. Como o habitual e ter cada clase nun arquivo, é necesario antes de instanciar o obxeto incluir o fichero coa definición da clase. Se hai moitas clases, isto pode ser un pouco lioso.

    Un truco consisten en gardar cada clase nun ficheiro que teña por nome, o nome da clase e extensión PHP (a clase unhaClase podémola gardar no ficheiro unhaClase.php). PHP5 cando necesita empregar unha clase e non a atopa definida, dase unha segunda oportunidade e chama a función __autoload(). Se a función esta definida, execútase, e nela temos que ser quen de cargar o arquivo coa clase que se necesita. Podese facer algo así:

    function __autoload($nome_da_clase) {
        require_once($nome_da_clase . '.php');
    }
    
    $obx1  = new claseUnha();
    $obx2 = new claseDuas();
    

    POO: E ti de quen vés sendo

    PHP No Comments »

    Hay unha serie de funcións que permiten obter información de obxetos e clases:

  • method_exists(obxeto,metodo)
  • property_exists(clase,propiedade)
  • class_exists(clase)
  • interface_exists(interface)
  • get_class_vars(clase)
  • get_class_methods(clase)
  • get_object_vars(obxeto)
  • get_class(obxeto)
  • get_parent_class(clase ou obxeto)
  • obxeto instanceof clase
    $obxeto1 = new clasePai();
    $obxeto2 = new clasePai();
    
    var_dump($obxeto1 instanceof claseNai); // Falso
    var_dump($obxeto1 instanceof clasePai); // Verdadeiro
    

    É importante ter en conta como funcionan os operadores de igualdade e identidade cos obxetos:

  • Dous obxetos son iguais == se son instancias da mesma clase e teñen as mesmas propiedades e valores
  • Dous obxetos son identicos === se son a mesma instancia dunha clase
  • $obxeto1 = new clasePai();
    $obxeto2 = new clasePai();
    
    var_dump($obxeto1 == $obxeto2); // E verdadeiro, son da mesma clase e cos mesmos valores nas propiedades
    var_dump($obxeto1 === $obxeto2); // E falso, son instancias distintas
    

    Deseñado por Norick - WPMU Theme pack by WPMU-DEV.
    Entries RSS Comments RSS Iniciar sesión