Blog

  • Qué son los métodos mágicos de PHP

    Qué son los métodos mágicos de PHP

    Una de las características que más me gusta de PHP son los métodos «mágicos».

    En realidad, como en la vida real, no se trata de magia como tal, si no de buenos trucos.

    De lo que se trata en este caso es de métodos que son invocados automáticamente (ante ciertos sucesos o eventos).

    La principal característica que tienen estos métodos es que sus nombres comienzan con __ (doble underscore).

    Si venís programando con objetos en PHP (al menos desde la versión 5), reconocerás estos (Especialmente el primero):

    __construct

    __destruct

    Puede que no lo supieras, pero el constructor y destructor de la clase pertenecen a un grupo más grande de métodos (conocidos como «mágicos»).

    Veamos algunos de ellos:

    __toString

    Este es otro de los más conocidos.

    Su función es retornar una cadena (string) que represente al objeto.

    Por ejemplo, si tuviéramos una clase Persona:

    <?php
    
    class Persona
    {
         private $nombre;
         private $apellido;
    
         public function __construct( $nombre, $apellido )
         {
                  $this->nombre = $nombre;
                  $this->apellido = $apellido;
          }
    }

    Podría resultar interesante que, al momento de imprimir por pantalla los datos de la persona se viera su nombre y su apellido.

    En este escenario podríamos definir un método __toString de la siguiente forma:

    public function __toString()
    {
        return $this->nombre.' '.$this->apellido;
    }

    Y luego hacer algo como:

    $persona = new Persona( "Mauro", "Chojrin" );
    
    echo $persona;

    Cuando el intérprete lea echo $persona automáticamente buscará en la definición de la clase Persona un método __toString y, si lo encuentra, lo invocará.

    Otros métodos mágicos interesantes

    Como decía, existen varios métodos mágicos que vale la pena conocer:

    __call

    El método __call es invocado en forma automática cuando se realiza una llamada a un método no definido explícitamente.

    En nuestro ejemplo anterior, sería el caso de invocar algo como $persona->intercambiar();.

    Lo primero que hará el intérprete será buscar un método específico llamado «intercambiar», al no encontrarlo buscará una definción de un método __call. En caso de encontrarla lo invocará pasando como parámetros el nombre del método buscado («intercambiar» en este caso y la lista de argumentos).

    La definición del método __call será algo como:

    public function __call( $metodo, array $argumentos )
    {
      ...
    }

    Este método es muy útil cuando se quiere armar familias de métodos similares.

    El ejemplo más claro que me viene a la mente es el que usaba Doctrine en su versión 1.

    Tenía un método findBy() que recibía un array de criterios de búsqueda.

    Muchas veces era muy cómodo poder escribir algo como findByName() (Donde «Name» se correspondía con el nombre de un campo de la tabla en cuestión).

    Es claro que Doctrine no puede adivinar todos los nombres de campos que a uno se le pueden ocurrir (y generar un método findByX()para cada uno…).

    Ahí entonces una solución posible (basada en __call) es algo como:

    public function __call( $method, array $arguments )
    {
       $find = "findBy";
    
       if ( substr( $method, 0, strlen( $find ) ) == $find ) {
           $field = substr( $method, strlen( $find ) );
        
           return $this->findBy( [ $field => $arguments[0] ] );
       }
    }

    De esta forma es posible llamar a cualquier método findByX como si estuviese definido.

    __set y __get

    Los métodos __set y __get son invocados cuando se intenta asignar (u obtener) una variable no pública de una clase.

    El contar con estos métodos permite, por ejemplo, ahorrar algo de código (No se requiere escribir un setter/getter para cada propiedad):

            public function __set( string $var, $val )
            {
                    $this->$var = $val;
            }
    
            public function __get( string $var )
            {
                    return $this->$var;
            }
    

    Y luego:

    $persona = new Persona( "Mauro", "Chojrin" );
    echo $persona->nombre.PHP_EOL;
    $persona->apellido = "Perez";
    echo $persona.PHP_EOL;

    Claro que, en este caso, bien podríamos haber dejado las variables como públicas y era más fácil, ¿cierto? :p

    Pero el tener estos métodos me permite también, por ejemplo, crear propiedades virtuales:

            public function __set( string $var, $val )
            {
                    if ( $var === "nombreCompleto" ) {
                            $parts = preg_split('/ /', $val);
                            $this->nombre = $parts[0];
                            $this->apellido = $parts[1];
                    } else {
                            $this->$var = $val;
                    }
            }
    
            public function __get( string $var )
            {
                    if ( $var === 'nombreCompleto' ) {
    
                            return $this->__toString();
                    }
                    return $this->$var;
            }

    Y al final:

    $persona = new Persona( "Mauro", "Chojrin" );
    $persona->nombreCompleto= "Miguel Perez";
    echo $persona->nombre.','.$persona->apellido.PHP_EOL;

    Más métodos mágicos

    Hay unos cuántos métodos mágicos más (algunos más útiles que otros, cierto) que podés consultar en la documentación oficial de PHP.

    Esta es una característica bastante avanzada que a veces se conoce también como meta-programación.

  • Cómo filtrar colecciones usando Doctrine ORM

    Estaba pensando cómo escribir este artículo en forma clara y didáctica y, después de darle algunas vueltas me pareció que lo más fácil era armar un video:

    Para más información sobre Doctrine podés consultar acá

  • Cómo llevar los cambios de una base de datos de desarrollo a producción

    Cómo llevar los cambios de una base de datos de desarrollo a producción

    Cuando tenemos una aplicación en producción (Es decir, siendo utilizada por usuarios reales) es muy común que nos encontremos con necesidades que no han sido cubiertas por el desarrollo original.

    Esto puede deberse a diversos factores como la falta de análisis, una pobre comprensión de la problemática a encarar o simplemente al hecho de que la realidad va cambiando conforme pasa el tiempo.

    Independientemente de cuál de éstas haya sido, cuando se detecta una necesidad que el software no cubre se requiere realizarle modificaciones para adaptarlo al nuevo escenario.

    Algunas veces los cambios en el código vienen de la mano de cambios en la estructura de la base de datos utilizada para dar soporte a la aplicación.

    Y ahí comienzan los problemas 🙂

    En un ambiente de trabajo profesional es muy común contar con diferentes entornos de ejecución.

    Al menos deberíamos tener dos:

    • Desarrollo (Donde trabajamos y los datos no son precisamente valiosos)
    • Producción (Donde trabajan los usuarios y los datos son sagrados).

    Parte de nuestro trabajo será realizar las modificaciones al código de la aplicación, probarlo y eventualmente desplegarlo en el servidor de producción.

    Para llevar el control de los cambios realizados sobre el código existen muchos sistemas de control de versiones, como por ejemplo Git o Subversion.

    Utilizar uno de estos sistemas simplifica mucho conseguir la perfecta sincronización entre el código que ejecutamos en nuestro entorno de desarollo y el de producción, pero… ¿cómo hacemos para que la estructura de la base de datos también esté sincronizada?

    Actualizar la base de datos manualmente

    El enfoque más simple consiste en aplicar los cambios a la base en forma manual.

    Esto significa entrar al servidor de bases de datos (Usando phpMyAdmin por ejemplo) y ejecutar los comandos que dejen la base en el estado deseado.

    Para usar esta estrategia no se necesita mucho más que buena memoria o buenas notas.

    Claro que la desventaja de este mecanismo es que es sumamente riesgoso y propenso a errores.

    Utilizar scripts SQL

    Otra opción más interesante es generar los scripts SQL que se utilizan durante el desarrollo y almacenarlos como parte del código, de modo de aprovechar el versionado de la propia aplicación.

    Este enfoque es mejor que el anterior ya que disminuye el riesgo de ejecutar comandos diferentes en cada ambiente y, de ese modo, minimiza las chances de terminar con estructuras de bases de datos distintas.

    Uno de los problemas que aún no resuelve este enfoque es cómo determinar de un modo simple cuáles cambios ya han sido aplicados y cuáles no.

    Versionar la base de datos

    Un enfoque alternativo es el uso de alguna herramienta para el versionado de la base de datos.

    En este esquema los cambios en el ambiente de desarrollo no se realizan escribiendo SQL, si no mediante código.

    Liquibase

    Liquibase es una herramienta basada en conjuntos de cambios (changeSets) descriptos usando diferentes lenguajes posibles (SQL, XML, Json o YAML).

    Una vez definidos los cambios que deben realizarse se utiliza el ejecutor de los cambios que es el encargado de verificar el estado actual, traducir los nuevos cambios a SQL e impactarlos.

    Migraciones de Doctrine

    Otra herramienta similar (y mi favorita :)) es el mecanismo de migraciones de Doctrine.

    Las migraciones son una parte de este gran ORM que describen los cambios que deben realizarse a la base de datos.

    Una gran ventaja de este mecanismo sobre Liquibase o similares es que todo el código se escribe utilizando puro PHP y al momento de ejecutar la migración queda a cargo de Doctrine realizar la traducción a SQL.

    Notas finales

    Como siempre, cuanto más automatizada sea nuestra operación más confiable será ya que podremos realizar tantos ensayos como necesitemos hasta contar con un mecanismo correcto.

    La contracara de utilizar una herramienta como esta es que es un camino de una sola vía: si no mantenemos la disciplina de escribir todos nuestros cambios del mismo modo nos vamos a encontrar con más problemas de soluciones… aunque, en la realidad, una vez que domines una de estas técnicas dificulto que quieras volver atrás 🙂

  • Cómo autenticar usuarios en WebServices SOAP usando PHP

    Cómo autenticar usuarios en WebServices SOAP usando PHP

    Muchas organizaciones (Especialmente gubernamentales) optan por exponer sus servicios web mediante el protocolo SOAP.

    Para hacer uso de dichos servicios es necesario consumirlos.

    Existen algunas ocasiones en las que no basta con conocer la URL del servicio, también es necesario realizar algún tipo de autenticación para obtener el resultado buscado.

    Autenticación HTTP en WebServices SOAP

    El método más simple de autenticación es el propio de HTTP.

    Si este es el caso, basta con generar una URL del estilo http://usuario@password:dominio/web_service para poder acceder.

    El principal problema de este método es su poca seguridad, ya que las credenciales viajan en cada pedido, por lo tanto, es bastante poco frecuente su uso en servicios web.

    En aplicaciones web normales podrías llegar a encontrártelo (o incluso podrías querer implementarlo).

    API-Key en WebServices SOAP

    Una segunda forma de realizar autenticación es aquella basada en las API-Keys.

    En este escenario, el proveedor del servicio debe decirte cuál es tu clave, la cual deberás enviar mediante algún encabezado como parte de tu petición.

    Para ello, asumiendo que utilices la clase SoapClient, deberás crear un nuevo contexto en el que basar tus peticiones, algo como:

    $soapclient = new SoapClient($wsdl, [ 
        'stream_context' => stream_context_create([ 
         'http'=> [ 
          'header' => "X-Api-Key: 1234abcd"    
         ] 
        ]) 
    ]); 

    Este esquema es algo más seguro, siempre y cuando se realice la comunicación a través de SSL.

    Autenticación via encabezados SOAP

    Otro esquema que suele utilizarse es el de la autenticación mediante encabezados SOAP.

    Este método permite que las credenciales viajen como parte del mensaje enviado lo cual puede ser deseable para evitar depender del protocolo subyacente (HTTP en la mayoría de los casos).

    Para lograrlo debes usar el método __setSoapHeaders y la clase SoapHeader.

    Ejemplo:

    $header = new SoapHeader(
                       $namespace,
                       'UserCredentials'
                       [
                             $UserID,
                             $Pwd
                       ]
    );
    
    $client->__setSoapHeaders($header);

    Claro que tanto el namespace como el nombre y estructura exacta del encabezado deberás validarlo contra el archivo WSDL del servicio al que te quieras conectar, pero la adaptación es simple.

    Autenticación vía WSSE

    Por último hay que mencionar un protocolo especial de seguridad para servicios web: WSSE (o WS-Security).

    Este protocolo es bastante complejo ya que incluye, entre otros, firmas digitales.

    Desafortunadamente, a la fecha no existe una implementación nativa de PHP para este tipo de autenticación, con lo cual no queda mucha opción que crear la nuestra o usar alguna desarrollada por un tercero.

    El punto clave aquí es hacer algunos toques a los encabezados que enviaremos.

    Para ello una buena opción es extender la clase SoapHeader de esta forma:

    class WsseAuthHeader extends SoapHeader 
    {
        private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
    
        function __construct($user, $pass, $ns = null) 
        {
            if ($ns) {
                $this->wss_ns = $ns;
            }
    
           $auth = new stdClass();
           $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns); 
           $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
    
           $username_token = new stdClass();
           $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns); 
    
           $security_sv = new SoapVar(
               new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
               SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
           parent::__construct($this->wss_ns, 'Security', $security_sv, true);
        }
    }

    Y luego simplemente se trata de agregar este nuevo encabezado a nuestro cliente:

    $client->__setSoapHeaders(new WsseAuthHeader( $UserID, $PWD));

    Y a partir de aquí ya es posible consumir los servicios con normalidad.

  • Cómo hacer un CRUD con Symfony e EasyAdmin

    Cómo hacer un CRUD con Symfony e EasyAdmin

    Me proponía escribir un artículo sobre lo bueno que es EasyAdmin, pero se me ocurró que una imagen vale más que 1000 palabras… Y un video más aún :). Así que armé este:

    Si lo disfrutaste y te quedaste con ganas de aprender más sobre Symfony el curso Introducción a Symfony Framework te puede ayudar.

  • Cómo generar facturas electrónicas usando PHP

    Cómo generar facturas electrónicas usando PHP

    En los países de Latinoamérica se está produciendo una migración hacia la facturación electrónica (dejando de lado las viejas facturas de papel).

    Más allá de aspectos políticos, es una muy buena noticia por, al menos, los siguientes motivos:

    1. Las operaciones comerciales se realizarán mucho más eficientemente
    2. Se limitará muchísimo la economía informal y todos los problemas que de ella se derivan
    3. Dará mucho trabajo a muchos programadores 🙂

    Sobre este último punto, veo que a muchos colegas se les complica un poco el tema de integrar sus sistemas con aquellos de la autoridad central de su país, así que decidí hacer este pequeño compendio de las librerías que hay disponibles como para acortar un poco el camino.

    Cómo generar facturas electrónicas para Argentina

    En el caso de Argentina, la autoridad central es la AFIP.

    La generación de facturas electrónicas se realiza mediante un WebService de tipo SOAP (La documentación oficial se puede consultar acá).

    Una clase que ya está implementada para hacer esto es la que desarrolló Ivan Muñoz.

    El código completo se encuentra en GitHub y mirando un poco, también hay un SDK para PHP que contiene esta librería y otras.

    Disclaimer: no probé su funcionamiento con lo cual no puedo dar garantías (¡Si tenés alguna experiencia y querés compartirla en los comments te lo agradezco!).

    Algunas observaciones de mirar el código nomás:

    • Está preparada para operar con composer
    • Podría tener mejores ejemplos
    • El código podría emprolijarse un poco (Usa notación de PHP 4, accede al php.ini desde la clase, etc…)

    La gente de BitIngenieria ha desarrollado también librerías para conectarse a diferentes organismos públicos (Entre ellos AFIP). Ahí podés encontrar mucho código listo para usar… sólo que es pago.

    Cómo generar facturas electrónicas para México

    En el caso de México, se puede usar el código publicado en http://www.lacorona.com.mx/fortiz/sat/codigo.php#intro por Fernando Ortiz.

    Es interesante cómo está presentado, no sólo el código fuente si no también el esquema de requests que deben hacerse para lograr el objetivo.

    Mirando el código simplemente veo:

    • Está escrito en modo procedural (En lugar de Orientado a Objetos)
    • El código podría estar mejor estructurado (Usa variables globales, incluye archivos dentro de funciones, etc…)
    • Usa SimpleXMLElement para procesar el XML
    • Tiene muy buena documentación
    • Es muy completo (Cubre una gran cantidad de casos)

    Tal vez no sería el que yo elegiría para implementar en forma directa, pero ciertamente es un excelente punto de partida.

    Cómo generar facturas electrónicas para Perú

    Aquí hay un tutorial interesante que explica paso a paso cómo hacer facturas electrónicas para Perú utilizando el webservice del SUNAT.

    No es exactamente lo que buscaba (Un SDK escrito en PHP), pero es un buen comienzo.

    La gente de NubeFact tiene una oferta para desarrolladores PHP (O para cualquiera bah) basada en un WebService REST propio (Que internamente se comunica con el WebService SOAP de SUNAT).

    Queda simplemente consumir el WebService REST de ellos (Y pagar por el servicio, claro… ojo que hasta 50 facturas diarias es gratis… para pensarlo).

    Cómo generar facturas electrónicas para Costa Rica

    Para el caso de Costa Rica tenemos esta API desarrollada por la comunidad CRLibre que permite comunicarse de forma simple con el Ministerio de Hacienda de Costa Rica.

    Su objetivo es ser un middleware que haga menos engorroso el desarrollo de este tipo de sistemas (Mostrando al desarrollador una cara más amigable).

    Por lo que parece no tiene aún un cliente de PHP (¡Vaya ironía!) pero parece un proyecto muy interesante y bien armado.

    Mirando un poco el código veo que también podría emprolijarse un poco (Hacerlo más acorde al paradigma de objetos, sacando referencias a variabels globales, etc…).

    Otro proyecto interesante que está disponible es Faktur-PHP-SDK desarrollado por una persona (o personas) llamada OpenCode506.

    No lo he probado funcionando, pero ya de ver el código me gusta bastante más que los otros que he comentado.

    Los puntos interesantes que le veo:

    1. Pide PHP 5.6 o superior (Ya implementa Namespaces por ejemplo)
    2. Viene con tests unitarios incorporados
    3. Está preparado para usarse vía composer

    Lo que podría ser un poco mejor es la documentación.

    Cómo generar facturas electrónicas para Uruguay

    Para el caso de Uruguay no encontré una implementación libre de facturas electrónicas… lo que vi es la documentación oficial y a través de una sesión de consulta conocí de la existencia de la empresa Sisnet que ofrece un middleware, sólo que hay que pagar por el servicio (y luego usar su webservice).

    Cómo generar facturas electrónicas para Chile

    Si tenés que generar facturas electrónicas para Chile podés usar la librería LibreDTE que desarrolló la gente de Sasco.

    A simple vista el proyecto parece sólido.

    Cumple con las caraterísticas básicas que tanto me gustan:

    1. Se puede instalar usando Composer
    2. Está muy bien documentada
    3. El código es moderno (Usa namespaces al menos)
    4. Tiene sus tests unitarios incorporados

    Cómo generar facturas electrónicas para España

    Por último, aunque estaba buscando sólo para LatinoAmérica, me crucé con una implementación de FacturaE para PHP desarrollada por José Miguel Moreno (Acá se puede ver el código).

    En resumen

    Habrás notado que, si bien cada país implementa su propia forma de Factura electrónica y por lo tanto se requiere una librería en particular, todas se basan en el mismo principio:

    1. Una entidad gubernamental expone un servicio web (Usualmente SOAP)
    2. La librería consume dicho servicio mostrando una API mucho más sencilla y amigable a los desarrolladores de a pié

    Con lo cual: si te encuentras en la situación de tener a mano una librería desarrollada para la facturación electrónica de tu país ¡úsala! En caso contrario (O que no te satisfaga completamente) para implementarla necesitará conocer cómo interactuar con WebServices en PHP.

    Si buscas ayuda sobre esto este curso puede serte útil.

  • Cómo recorrer un archivo XML usando PHP

    Cómo recorrer un archivo XML usando PHP

    Como de costumbre, comencemos por ponernos de acuerdo en las definiciones.

    Qué es XML

    Las siglas XML remiten a eXtensible Markup Language (Lenguaje de etiquetas extendible).

    Se trata de texto estructurado mediante etiquetas (Palabras encerradas entre < y >):

    <utensilios>
      <tenedor/>
      <cuchillo/>
    </utensilios>
    

    Para qué sirve XML

    XML se inventó como un medio de intercambio de información entre sistemas a través de Internet. Al ser un formato basado en texto, era fácil aprovechar la infraestructura existente para comunicarse a través de HTTP.

    Hoy en día, XML es utilizado en muchas implementaciones de WebServices (Por ejemplo, las facturas electrónicas) y también para almacenar configuraciones (En el caso del lenguaje Java es muy común encontrar este tipo de archivos, en PHP no tanto).

    Cómo se procesa XML usando PHP

    Al tratarse de texto, un modo de procesar XML es, como cualquier otro texto… pueden usarse expresiones regulares u otro medio de análisis de texto para interpretar y/o generar las etiquetas.

    Claro que no es muy divertido que digamos…


    Para comprender completamente lo que viene a continuación se requieren conocimientos de Programación Orientada a Objetos con PHP. Si aún no lo tenés muy claro este curso te puede ayudar.


    Otro modo bastante más práctico es usar la biblioteca SimpleXML que viene con PHP.

    La clase principal de la biblioteca es SimpleXMLElement. Con esta clase se puede crear una estructura en memoria a partir de un texto XML y luego recorrerlo en forma sencilla.

    Ejemplo de lectura de XML con SimpleXMLElement

    El constructor de SimpleXMLElement recibe un texto XML:

    <?php
    $xml = new SimpleXMLElement( '<utensilios><tenedor/><cuchillo/></utensilios>' );

    Y a partir de ahí pueden realizarse diversas operaciones para recorrer los elementos.

    Una de ellas es buscar elementos explícitamente a través de su XPATH:

    $elementos = $xml->xpath('/utensilios/tenedor');

    Esta llamada dejará en el array $elementos todos los nodos tenedor que se encuentren bajo la clave utensilios (En este caso es sólo uno, pero eso SimpleXMLElement no lo sabe a priori).

    Si agregamos un print_r( $elementos ) veremos :

    Array
    (
        [0] => SimpleXMLElement Object
            (
            )
    
    )

    Es decir, un array con un único elemento… de tipo SimpleXMLElement, al que podemos nuevamente aplicarle todas las funciones que provee la clase.

    Ejemplo de recorrida de XML con SimpleXML

    Otra forma de recorrer el texto XML es a través del método children:

    <?php
    $xml = new SimpleXMLElement( '<utensilios><tenedor/><cuchillo/></utensilios>' );
    foreach ( $xml->children() as $child ) {
            print_r( $child );
    }

    Esta es la que deberías usar si no conoces exactamente la estructura del XML o si efectivamente tenés que recorrer el archivo completo.

    Cómo leer un archivo XML usando PHP

    Bueno, con lo que viste hasta ahora el paso que queda es realmente corto… se podría leer el contenido del archivo a una variable y pasarla al constructor de SimpleXMLElement:

    <?php
    $texto = file( 'archivo.xml' );
    $xml = new SimpleXMLElement( $texto );
    $elementos = $xml->xpath('/utensilios/tenedor');
    print_r( $elementos );

    O bien pasar directamente la ruta al archivo al constructor:

    <?php
    $xml = new SimpleXMLElement( 'archivo.xml' );
    $elementos = $xml->xpath('/utensilios/tenedor');
    print_r( $elementos );

    Y dejar que SimpleXML se encargue de interpretar si se trata de uno u otro.

    Conclusión

    Si todavía no te convencí de usar SimpleXML en lugar de hacer las cosas a mano, te invito a leer un poco más sobre el formato XML (Especialmente el manejo de namespaces).

    Ahora, si tenés que interactuar con un sistema que está implementado usando XML, bueno… no hay muchas opciones.

    Si, por el contrario, estás pensando en usar algún formato de texto para guardar configuración o incluso para intercambiar con otros sistemas, te sugiero darle una mirada a JSON o a YAML

  • Cómo acelerar un sitio desarrollado con PHP

    Cómo acelerar un sitio desarrollado con PHP

    Por qué invertir en acelerar un sitio web

    La primera pregunta que uno se haría ante esta situación es: ¿para qué molestarse? 🙂

    Es decir, cualquiera preferiría un sitio rápido antes que uno lento, ¿cierto?

    Pero… ¿para qué sirve realmente tener un sitio más rápido?

    Bueno pues hay dos respuestas inmediatas:

    1. Mejor experiencia de usuario
    2. Mejor posicionamiento orgánico

    Ambas redundan en beneficios muy palpables para los dueños de los sitios: clientes más satisfechos y mayor afluencia de potenciales clientes.

    Qué factores influyen

    Muy bien, ahora que estamos de acuerdo en que tener un sitio rápido es beneficioso tenemos que comprender qué factores influyen en la velocidad de carga.

    La realidad es que son muchos y, lamentablemente, unos cuantos están fuera de nuestro control, pero igualmente analicémoslos un momento.

    Toda la interacción con un servidor web se basa en:

    • Una traducción de un nombre de dominio en una dirección IP
    • El establecimiento de una conexión entre el cliente y el servidor
    • El envío de información desde el cliente hacia el servidor
    • La resolución del pedido por parte del servidor
    • El envío de información desde el servidor al cliente
    • El rendering del lado del cliente

    Como puede verse, un factor decisivo será la velocidad de la red subyacente en esta comunicación (Lo que se conoce como ancho de banda) pero definitivamente no es el único.

    De modo que existen medidas que pueden tomarse para mejorar el tiempo del lado del cliente (frontend) y otras tantas del lado del servidor (backend).

    Cómo acelerar el frontend de una aplicación Web

    Acelerar el frontend implica minimizar:

    • La cantidad de pedidos al servidor
    • La cantidad de información intercambiada en cada pedido
    • El tiempo que insume el rendering

    Un típico cuello de botella lo encontramos en el tamaño de las imágenes u otros archivos estáticos (JavaScript, CSS, etc…).

    Reduciendo estos es posible ganar mucho.

    Una herramienta muy útil para medir estos cuellos de botella es GTMetrix

    Cómo acelerar el backend de una aplicación Web

    Y luego está la otra cara de la moneda: el servidor.

    ¿Qué podemos hacer para que nuestro servidor responda más rápido?

    Nuevamente, tenemos que saber a dónde apuntar nuestros cañones.

    Usualmente una aplicación web consiste en:

    • Un webserver
    • Una base de datos
    • Algún script

    En nuestro caso asumiremos que se trata de PHP, aunque los principios aplican para cualquier lenguaje.

    Es muy probable que la parte más compleja de optimizar sea el código de la aplicación.

    Principalmente porque lograr el mismo resultado usando mejor código requiere mucho análisis y, sobre todo, mucho testing para asegurarnos de no romper nada en el camino.

    Hay unas cuantas mejoras que pueden hacerse desde la infraestructura que son muy simples y aportan mucho. Por ejemplo:

    • Distribuir la carga a través de un CDN
    • Enviar el contenido comprimido
    • Usar algún minificador de CSS/JS
    • Usar un caché agresivo en el webserver
    • Usar PHP vía PHP-FPM

    Y luego hay otras herramientas que complementan al servidor web como ser los cachés de memoria (APC, Memcached, Redis, etc…)

    También vale la pena investigar qué consultas pueden estar trabando la base de datos, por ejemplo usando el MySQL slow query log e intentar mejorarlas.

    Y por último, si sospechamos que el código está haciendo de las suyas podemos usar un profiler como XDebug para orientarnos sobre dónde poner la lupa.

    Conclusión

    En definitiva, acelerar un sitio web lento es perfectamente posible pero también bastante laborioso.

    Siempre debe primar un criterio de costo/beneficio para saber cuando se ha alcanzado una velocidad aceptable y ya no vale la pena el esfuerzo de seguir mejorándolo.

  • ¿Es posible hostear una aplicación PHP en Windows?

    ¿Es posible hostear una aplicación PHP en Windows?

    Un amigo me contactó por un problema que estaba enfrentando su equipo técnico: están desarrollando una aplicación PHP que necesitan hostear sí o sí en un servidor Windows.

    Actualmente tienen un IIS montado en su servidor y la duda era, primero si era posible servir PHP desde IIS o si era necesario usar un servidor Apache y, en tal caso, si era necesario compilarlo desde 0 (Algo que estaba fuera del alcance de dicho equipo).

    Mi primera impresión ante esta situación fue de sorpresa. Ciertamente, Windows no sería mi elección en cuanto a servidor (En general prefiero mantenerme alejado de Windows, pero especialmente para el caso de servidores soy bastante estricto).

    Yo optaría por alguna distribución de linux (Probablemente basada en Debian como para hacer las cosas sencillas, pero en DistroWatch siempre se encuentran sorpresas interesantes) y, de ser posible iría con un VPS montado en DigitalOcean.

    Ahora bien, intentaré responder las preguntas de a una.

    ¿Puede IIS servir PHP?

    Sí.

    De hecho, Microsoft tiene un sitio especialmente dedicado al tema en https://php.iis.net/

    Un pequeño detalle es que este sitio ha quedado algo desactualizado… habla de la versión 5.3 de php :p, pero se pueden seguir estas instrucciones para actualizar la versión a alguna más moderna.

    ¿Puede Apache instalarse en Windows?

    Sí.

    El webserver Apache está escrito en lenguaje C con lo cuál, puede crearse una versión especial para cualquier plataforma que tenga un compilador de ese lenguaje (Tal es el caso de Windows).

    ¿Es necesario compilar Apache desde cero para instalarlo en Windows?

    No.

    Apache puede ser instalado directamente descargando los binarios (sólo que no los podrás obtener del sitio oficial del proyecto que sólo tiene el código fuente).

    Un par de lugares donde podés conseguir los binarios de Windows:

    Y si te interesa el «paquete completo» podés usar alguno de los que viene ya con MySQL y PHP:

    Sí es cierto que al compilar el Apache vos mismo tenés más control sobre lo que instalás en tu servidor (¡Pero también podés hacer mucho lío si no sabés lo que estás haciendo!).

    Conclusión

    Es perfectamente posible hostear una aplicación PHP en un servidor Windows. Las opciones son muchas y, como de costumbre, no existe una que sea universalmente mejor que las otras, será cuestión de evaluar tus posibilidades y decidir cuál es el mejor camino.

  • Qué se necesita para poner online una aplicación PHP

    Qué se necesita para poner online una aplicación PHP

    Una pregunta que parece algo obvia, ¿no? Lo que se necesita para poner en línea una aplicación PHP es un hosting. No hay mucho más que decir al respecto, ¿cierto? Pues… tal vez convenga hilar un poco más fino.

    Si bien en sus inicios PHP se utilizaba exclusivamente para la creación de aplicaciones web, hoy en día abarca un abanico mucho más amplio.

    En este artículo me centraré en la infraestructura mínima necesaria para poner en línea una aplicación web desarrollada con PHP.

    Qué debe tener un servidor para hostear una aplicación PHP

    Lo primero que debemos comprender es que, para que una aplicación web esté en línea, independientemente del lenguaje en que esté desarrollada, se requiere:

    1. Que el código esté disponible en alguna computadora conectada a Internet (El Servidor)
    2. Que dicha computadora cuente con algún software capaz de recibir peticiones a través de Internet (El WebServer) instalado y funcionando
    3. Que la dirección IP de esa computadora sea conocida en forma pública (o fácilmente averiguable)

    En el caso de PHP un requisito adicional es que esté presente en el servidor un software capaz de interpretar y ejecutar el código (El intérprete).

    Existen muchas combinaciones diferentes de software que se encargan de esto, entre las más conocidas podemos encontrar:

    Incluso es posible utilizar el Internet Information Server si el sistema operativo del servidor es Windows.

    Luego será necesario configurar el servidor web de modo que ciertas peticiones sean derivadas al intérprete de php (A diferencia de otras que simplemente deben ser servidas enviando el contenido de los archivos solicitados).

    Esta configuración es diferente según el paquete de software con que se cuente.

    Qué servicios aparte del hosting se necesitan para poner online una aplicación PHP

    Usualmente, cuando se desea poner un sitio en línea, se busca que los visitantes accedan al mismo a través de una dirección sencilla de recordar (Lo que se conoce como un dominio), sin embargo, para que la computadora cliente pueda conectarse a la computadora servidor es necesario conocer su dirección IP.

    Para ello existe un servicio adicional: el DNS.

    De modo que, para que nuestro sitio esté disponible al público será necesario, además de registrar un dominio, configurar el DNS para que realice esa traducción.

    Luego, dependiendo de las necesidades específicas del sitio que queremos montar, es probable que sea necesaria la instalación de algún software de gestión de bases de datos (Como MySQL, PostGre o alguno similar).

    Respecto de la computadora que actuará como servidor, existen diferentes opciones (de diferentes costos y requisitos técnicos).

    Se puede usar una computadora personal propia, contratar espacio en un servidor compartido, comprar una computadora y dejarla en un proveedor que garantice la alimentación y conectividad, usar un servidor virtual… en fin, las opciones son muchas.

    ¿Te cuesta decidir? Este post puede ayudarte.