Blog de Javier Negreira

Cuaderno de un desarrollador de software

Cómo instalar XAMPP para tener un entorno de desarrollo web

Vamos a preparar nuestro ordenador para trabajar en el desarrollo de un proyecto web usando XAMPP, no importa si es para un Symfony PHP, Laravel, WordPress, Joomla, u otro proyecto PHP. Tenemos versiones de XAMPP para Windows, OSX, o como en este caso, un Ubuntu 16.04 Desktop.

Podemos preparar nuestro ordenador para desarrollar en local un proyecto web de varias formas.

  • Instalando y configurando todos los servicios de un servidor web en local (Apache, PHP, MySQL, y extras). Tiene el inconveniente de que nos llevará unas horas configurarlo todo, y la máquina queda un tanto “sucia”, al estar siempre ejecutando esos servicios, consumiendo memoria, se hace difícil probar una actualización del PHP ya que esto afecta a todos los proyectos. Por suerte, hay alternativas.
  • Usando una máquina virtual, con VirtualBox o VM Ware, configurada con todos los servicios. Es mejor opción que la anterior, el SO anfitrión queda más limpio, se pueden tener varias máquinas virtuales con diferentes versiones de PHP, MySQL o servidor web. Sus inconvenientes, que la máquina virtual consume bastante memoria y procesador, la velocidad de respuesta es peor, por ejemplo, si usas VirtualBox se relentiza mucho si compartes una carpeta con muchos archivos entre el anfitrión y la máquina virtual, lo cual afecta mucho a la respuesta del Apache (ya hablaremos en otro post sobre esta prueba), tarda un poco más en arrancar, los discos virtuales suelen ocupar varios Gb, lo que puede ser un inconveniente si queremos tener muchas máquinas distintas. Aun así, es una opción interesante. Si quieres probarlo, te recomiendo que veas el proyecto Vagrant y la máquina Homestead permite descargar y arrancar una máquina completamente configurada con Ubuntu 14.04, Git, PHP 7.0, HHVM, Nginx, MySQL, MariaDB, Sqlite3, Postgres, Composer, Node (con PM2, Bower, Grunt, and Gulp), Redis, Memcached y Beanstalkd.
  • Instalar XAMPP, un paquete preparado por Apache con los servicios necesarios para tener un entorno de desarrollo en PHP (o Perl) en local, configurado y listo para ejecutarse standalone. Las ventajas, ocupa poco, sólo se arranca cuando se necesita, al no ejecutarse en un entorno virtual su rendimiento es mejor al de la máquina virtual.

Tras haber probado las tres, sin duda me decanto por utilizar XAMPP, así que vamos a describir los pasos a seguir para su instalación en un Ubuntu 16.04.

(Extra) Está surgiendo una nueva manera de distribuir aplicaciones a través de Docker, un sistema a base de contenedores donde no sólo está el código fuente, sino cada uno de los servicios que necesita (servidor web, de base de datos, etc), de forma que tanto en local como en producción se trabaja exactamente con el mismo entorno (adiós al “en mi máquina funciona” :)). Esto también facilita el cambiar de proveedor de Hosting. Parece un sistema muy prometedor. Hablaremos en el futuro.

La instalación no puede ser más sencilla:

Pasos para instalar XAMPP

  • Descargarlo de la página de Apache. Hay varias versiones de PHP y MySQL para elegir, tanto para Windows, OSX como para Linux. En este momento, la versión con PHP7 para para Linux, nos descarga este archivo:
    xampp-linux-x64-7.0.6-0-<wbr />installer.run

    Contiene:
    Apache 2.4.18, MariaDB 10.1.13, PHP 7.0.6 + SQLite 2.8.17/3.7.17 + multibyte (mbstring) support, Perl 5.16.3, ProFTPD 1.3.4c, phpMyAdmin 4.5.2, OpenSSL 1.0.2h, GD 2.0.35, Freetype2 2.4.8, libpng 1.5.26, gdbm 1.8.3, zlib 1.2.8, expat 2.0.1, Sablotron 1.0.3, libxml 2.0.1, Ming 0.4.5, Webalizer 2.23-05, pdf class 0.11.7, ncurses 5.9, pdf class 0.11.7, mod_perl 2.0.8-dev, FreeTDS 0.91, gettext 0.18.1.1, IMAP C-Client 2007e, OpenLDAP (client) 2.4.21, mcrypt 2.5.8, mhash 0.9.9.9, cUrl 7.45.0, libxslt 1.1.28, libapreq 2.12, FPDF 1.7, ICU4C Library 4.8.1, APR 1.5.2, APR-utils 1.5.4

  • Marcar el archivo descargado como archivo ejecutable, bien sea desde las preferencias del archivo:

    captura-de-pantalla-de-2016-06-10-114208

    Dar permisos de ejecución a fichero en nautilus

    o mediante la consola de comandos:

    chmod +x xampp-linux-x64-7.0.6-0-<wbr />installer.run

    asistente-instalador-xampp

  • Ejecutarlo con privilegios de root, por lo tanto, usaremos sudo:
    sudo ./xampp-linux-x64-7.0.6-0-<wbr />installer.run

    Nos dirá que va a instalar los paquetes XAMPP Core Files, y nos pregunta si queremos instalar los XAMPP Developers Files. Por defecto instala los dos. Continuamos.
    Nos informa de que será instalado en la carpeta /opt/lampp.

    captura-de-pantalla-de-2016-06-10-115142

  • En apenas 1 minuto nos informará de que tenemos el XAMPP instalado y configurado. Nos preguntará si queremos arrancarlo (ya que arrancamos y apagamos a demanda). Si le indicas que si, te abrirá el navegador publicando una página de bienvenida:

    captura-de-pantalla-de-2016-06-10-115847

    Ejemplo página bienvenida XAMPP

¡¡ Listo !! Ya tienes un servidor web preparado para trabajar en local :). ¿Sencillo, verdad?. Ya puedes comenzar con tu proyecto Symfony, Laravel, WordPress, o lo que tengas pensado.

Algunos trucos

Ahora vamos a hacer algunas mejoras, para tenerlo todo un poco más cómodo.

Hacer accesible el intérprete de comandos PHP en todo el sistema operativo

De esta forma, el comando php estará disponible desde cualquier parte. Lo haremos creando un enlace simbólico:

sudo ln -s /opt/lampp/bin/php /usr/local/bin/php

Instalar XDEBUG

Un imprescindible, para poder debuguear vuestro código.
La forma de instalarlo varía dependiendo de la versión de XAMPP elegida, por lo que os remito al asistente de su página oficial donde os dirá los pasos a seguir, a partir de la información que os da el phpinfo().

Activar los Virtual Host de Apache (VHosts)

Los Virtual Host nos permiten tener mejor organizados los proyectos, cada uno con su dominio propio, cada uno apuntando a su carpeta propia, con ficheros de log separados, por ejemplo que nuestro “proyecto1” se publique en el dominio “proyecto1.dev”, y el “proyecto2” se publique en el dominio “proyecto2.dev”. (No mas proyectos publicados directamente en localhost :))

Editar el archivo httpd.conf:

sudo gedit /opt/lampp/etc/httpd.conf

y descomentar la línea:

Include etc/extra/httpd-vhosts.conf

Ahora, editar el archivo:

/opt/lampp/etc/extra/httpd-<wbr />vhosts.conf

… y configurar cada uno de los proyectos. Por ejemplo, digamos que queremos trabajar en un proyecto con WordPress en local, que ubicaremos en la carpeta /home/mi-usuario/sites/mi-wordpress, y que responda en la URL http://mi-wordpress.dev/. Añadiremos en el httpd-vhosts.conf:


    ServerAdmin admin@mi-wordpress.dev
    DocumentRoot /home/mi-usuario/sites/mi-<wbr />wordpress
    ServerName mi-wordpress.dev
    ServerAlias www.mi-wordpress.dev
    ErrorLog logs/mi-wordpress.dev-error_<wbr />log
    CustomLog logs/mi-wordpress.dev-access_<wbr />log common
    
       AllowOverride all
       Require all granted
    

Vamos a dar de alta en local el dominio mi-wordpress.dev para que apunte a la máquina local. Editamos el archivo hosts:

sudo gedit /etc/hosts

Y añadimos un nuevo dominio local:

127.0.0.1   mi-wordpress.dev
En este momento, el nuevo dominio debe responder a un ping:
PING mi-wordpress.dev (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.030 ms

Reiniciamos el xampp (cada vez que se cambie el vhost, es necesario reiniciar el Apache para que surja efecto):

sudo /opt/lampp/lampp restart

¡¡ Ya está !!. Para probarlo, creemos el fichero /home/mi-usuario/sites/mi-wordpress/phpinfo.php, con:

Hola mundo

Y escribamos en el navegador http://mi-wordpress.dev/phpinfo.php

Ejemplo sitio vhost apache funcionando phpinfo

Ejemplo sitio vhost apache funcionando phpinfo

Comandos que debes tener a mano

Arrancar los servicios (apache, mysql, ftp):

sudo /opt/lampp/lampp start

Parar los servicios:

sudo /opt/lampp/lampp stop

Reiniciar los servicios:

sudo /opt/lampp/lampp restart

Ficheros que puedes necesitar tocar

Configuración del PHP:

/opt/lampp/etc/php.ini

Configuración del Apache:

/opt/lampp/etc/httpd.conf
/opt/lampp/etc/extra/httpd-<wbr />xampp.conf

Configuración de los Virtual Host de Apache (VHosts):

/opt/lampp/etc/extra/httpd-<wbr />vhosts.conf

Desinstalación

Basta con borrar la carpeta:

sudo rm -rf /opt/lampp

Si conoces algún otro truco para hacer el entorno más cómodo, por favor, compártelo en los comentarios. 🙂

¿Por qué Symfony?

En el momento en el que uno comienza a pensar en el diseño técnico que necesita para desarrollar el back-end de una aplicación web de complejidad media/alta, enseguida se da cuenta que intentar abarcarlo todo con código PHP nativo no es práctico. Tareas como gestionar las plantillas de front-end, acceso a base de datos, gestión de formularios, validaciones, variables de sesión, etc … tienen una implementación un tanto costosa en PHP nativo, y en muchos casos obligan a casarse con determinadas herramientas, cuando fácilmente podría abstraerse de ellas (como puede ser la elección del gestor de base de datos).

Uno puede verse tentado a desarrollar sus propias librerías (“esto me lo hago yo en un periquete“). Personalmente pienso que eso es un gran error. Esa filosofía está bien mientras uno está estudiando y formándose, para entender mejor como funcionan las cosas por dentro, pero en cuanto estamos en el mercado laboral y tenemos que ofrecer a nuestros clientes productos de calidad en un plazo de tiempo razonable, pensar que nosotros solos, por nuestra cuenta, somos capaces de desarrollar todas estas librerías, con una calidad similar que las comunidades de desarrolladores experimentados, suena un tanto pretencioso, ¿no crees? :-). (1)

¡¡ No reinventes la rueda !!. En el 99.99% de los casos, el mismo problema que tienes ahora encima de la mesa, lo han tenido miles de personas antes, y te explican como resolverlo correctamente.

Es aquí donde aparecen los frameworks, para facilitarnos la vida poniendo a disposición del desarrollador un conjunto estandarizado de conceptos, buenas prácticas, criterios, y librerías, que le ayuden a preocuparse por el negocio de su cliente, y no por decidir donde ubicar una librería, o como hay que hacer para guardar un registro en la base de datos. (Di NO al código espagueti).

Hay donde elegir

Existen bastante competencia entre la que elegir, cada uno con sus ventajas e inconvenientes. Entre los mas relevantes, podemos encontrar: Symfony, Zend framework, Laravel, CakePHP, Yii, Phalcon, CodeIgniter.

También existen los micro-frameworks, versiones sencillas y ligeras de fácil instalación. Symfony tiene un hermano pequeño llamado Silex.

¿Con cual me quedo?
Pues no se puede decir que haya un ganador absoluto. Aunque tienen muchos puntos en común, cada uno implementa una aproximación diferente para solucionar problemas similares, unos mejor que otros. Influye mucho el proyecto en el que va a ser aplicado: volumen de tráfico previsto, necesidades de integración con herramientas que ya tenga el cliente, etc.

Durante la toma de requisitos, evalúa si lo que te pide el cliente se puede resolver con alguna herramienta que ya exista en el mercado, lo que te ahorrará tiempo y costes. Si simplemente quiere una página sencilla para tener presencia online y/o un blog, lo resuelves con un WordPress, si quiere una tienda online, mejor configúrale un PrestaShop, Magento, o un Shopify, si quiere un foro mira phpBB o similar, si quiere algo más complejo aún puede encajar en las funcionalidades de algún CMS como Drupal o similar.

En mi caso particular, pensando en que el tipo de aplicaciones que vamos abordar son de complejidad media y alta, veo que Symfony es la herramienta adecuada. Quiero compartir con vosotros el análisis que me ha llevado a esta conclusión.

Los pilares

El core de Symfony se basa en la integración de 4 productos muy potentes ya existentes en el mercado, que podríamos haber instalado de forma individual en nuestra aplicación:

Un motor de plantillas “rápido, seguro y flexible“, también propiedad de SensioLabs. Resuelve a la perfección la separación de la renderización de las vistas del patrón MVC. Permite herencia de plantillas, de forma que defines un layout general, y bloques de código html, similares a widgets, que son embebidos en cualquier parte del layout. Es extensible mediante el sistema de Bundles de Symfony, de forma que se pueden añadir nuevas funcionalidades muy fácilmente, como ejemplo, la manipulación de imágenes y generación de thumbnails con LiipImagineBundle, entre otros, o gestionar la personalización temas mediante LiipThemeBundle.

Un ORM (mapeador de objetos-relacional) que nos facilitará mucho la vida a la hora de trabajar con la capa de persistencia en base de datos (después de pillarle el truco a los archivos de definición de las entidades y las relaciones entre ellas, que no es inmediato), de mostrar/renderizar la información de una entidad y sus relacionadas en una página html, de transformarla en estructuras JSON o XML, de abstraernos el motor de base de datos a utilizar, de balancear entre las máquinas de un cluster de servidores maestros / esclavos según estemos actualizando o solo consultando, con drivers para conectaros a los motores más habituales (MySQL, PostgreSQL, Oracle, MS-SQL Server, SQL Lite, SAP Sybase SQL), y también a NoSQL como MongoDB.

Librería para el envío de correos electrónicos. Permite usar SMTP, sendmail, Postfix o un transporter personalizado, como por ejemplo GMail, de forma sencilla, soporta servidores que necesitan autentificación, fácil integración para envío de contenido HTML y texto plano alternativo, adjuntos, sistema de encolado de emails, con plugins para controlar libreración gradual de los correos, registro de la traza de toda la comunicación con el servidor SMTP saliente, y más.

Librería para registro de la actividad de una aplicación en ficheros de log, que implementa el estandar PSR-3. Define 9 niveles de criticidad de un mensaje (log, debug, info, notice, warning, error, critical, alert, emergency), permite registrarlas en archivos de disco, base de datos, notificación por correo electrónico, definición de diferentes canales de logueo, y más. Por ejemplo, permite definir un canal por el cual, si la aplicación registra un mensaje de nivel error o superior, que lo guarde en un archivo de disco, y envíe un correo electrónico al equipo de soporte.

Ampliable

Este es uno de los puntos fuertes. En los pilares de la estructura de Symfony se encuentra la de organizar las funcionalidades en paquetes, o Bundles (en su propia terminología). ¿Necesitas algo que no viene en el core?. Lo más probable es que alguien haya tenido antes la misma necesidad, así que antes de ponerte a desarrollarlo por tu cuenta, consulta si existe algún Bundle que puedas instalar en tu aplicación que lo resuelva. (Mejor será invertir media mañana y encontrar un Bundle de calidad que resuelve correctamente el problema, que no gastar días de trabajo en hacer algo ad-hoc).

Hay centenares de Bundles disponibles. Esta es una lista de los 30 Bundles más interesantes y usados, según el propio SensioLabs, o esta lista de bundles populares, según Symfony.es.

A modo de introducción, nos podemos encontrar:
FOSUserBundle, para resolver el problema de alta de usuarios, confirmación de la dirección de email, gestión de olvidos de contraseña, etc.
HWIOAuthBundle Para habilitar que los usuarios se registren en tu plataforma con sus cuentas de Facebook, Twitter, Google+, y muchas mas (aquellas que permitan la autentificación mediante OAuth).
FOSRestBundle para habilitar fácil y rápidamente un API Rest.
JMSSerializerBundle para transformar tus entidades a estructuras JSON, XML y/o YAML.
LiipImagineBundle para el tratamiento de imágenes (crear miniaturas/thumbnails, añadir marcas de agua, recortar, rotar, etc).
StofDoctrineExtensionsBundle añade funcionalidades extra a las entidades que almacenaremos en base de datos, como son definir listas ordenables (sortable), listas en árbol (tree), atributos que hacen referencia a un archivo subido por el usuario (uploadeable), atributos que registren automaticamente la fecha y hora de guardado, atributos de texto que pueden tener traducción en varios idiomas, y más.
JMSSecurityExtraBundle añade funcionalidades y facilita la gestión de permisos de acceso a los diferentes recursos y urls de nuestro sitio, de forma rápida, sin necesidad de tener que activar el pesado ACL o los Voters.

En ocasiones, te puedes encontrar un Bundle que si resuelve el problema que tienes, pero no de la forma que te habías imaginado. En este momento deberías preguntarte: ¿Me puedo adaptar yo (y mi aplicación) a como resuelve este bundle mi problema?. En la mayoría de los casos, la respuesta debería ser SI, y ser tú quien te adaptes. De esta forma, te estarás alineando con las buenas prácticas que llevan implícitos los Bundles de calidad, aprovecharás las actualizaciones y mejoras que aporte la comunidad que lo soporta, facilitarás el trabajo futuro de mantenimiento, para ti y/o para el equipo encargado. Por norma, suele haber mas ventajas que inconvenientes.

Buenas prácticas

Symfony sigue un conjunto de buenas prácticas determinadas por la comunidad para el desarrollo de software, como son:

Programación orientada a objetos (OOP)
Modelo Vista Controlador (MVC)
Inyección de dependencias (DI)
Mapeador de objetos relacional (ORM)
Internacionalización (i18n)
Coding Standars
– Helpers
REST
JSON-RPC
Scaffolding
Configuración mediante archivos YAML
Annotations
Mecanismo de caché
Autentificación y Autorización
– Sistemas de seguridad para evitar ataques por fuerza bruta, CSRF, SQL Injection, etc.
Integración con pruebas unitarias (TDD) y de comportamiento (BDD)

Documentación, aprendizaje y comunidad

La curva de aprendizaje en Symfony no es trivial, más exigente que en otros frameworks mas livianos, pero comparada con Zend, sin duda es menos dolorosa. La documentación de Zend parece estar orientada para los desarrolladores del framework, no para personas no iniciadas. En su lugar, Symfony publica una documentación bastante completa, con un Cookbook que provee de ejemplos bastante claros de como utilizar las principales características (aunque a veces solo detalla el caso de uso más relevante según su criterio, y omite explicar para que sirven otros parámetros o valores, lo que obliga a investigar por la red).

A día de hoy, Google nos dice que Symfony es el más popular entre ellos. Esto dice algo muy positivo, y es que hay una amplia comunidad de gente activa interesándose y colaborando con este framework. En stackoverflow.com podemos encontrar mucha ayuda, y respuestas a preguntas frecuentes.

Con las manos en la masa

Al ser tan popular, los IDE más utilizados se han preparado para mejorar la integración y la experiencia de desarrollo, reconociendo code completion, coding style, atajos para acceder a la definición de métodos, clases, ficheros de configuración, etc., como es el caso de los plugins para Netbeans, Eclipse, Sublime, o el prestigioso (y de pago) phpStorm.

En el entorno de desarrollo, incluye automáticamente en el pie de cada página una Debug toolbar and Profiler de gran utilidad, pudiendo acceder desde ahí a mucha información relevante para el desarrollador. (Basta ya de tanto print_r y var_dump).

Mediante la Consola de comandos podremos ejecutar proceso batch, tanto desarrollados por nosotros, como funcionalidades propias de Symfony.

Integración con otras herramientas

Existen Bundles para conectar con herramientas de terceros, como:
phpDocumentator
Memcached o Redis
PHPUnit y Behat
Capistrano

… entre muchas.

Casos de éxito

Como me decía un antiguo jefe: “los experimentos en casa, y con gaseosa“. Con esto nos quería transmitir que para su negocio necesitaba herramientas contrastadas en las que pudiera confiar. En este sentido, tanto Zend Framework como Symfony destacan por su grado de madurez.

Entre los proyectos de envergadura que funcionan con Symfony podemos encontrar a TED, Dailymotion, Yahoo! Answers, Yahoo! Bookmarks, delicious.com, eZ Publish o Drupal (desde su versión 8).

El equipo de Octivi nos detalla el caso de éxito de esta aplicación que responde 1,000 millones de peticiones por semana con un tiempo medio de respuesta de 30 milisegundos. A través de High Scalability sabemos que lo han conseguido con tres servidores de la aplicación front (HAProxy, PHP-FPM, Varnish), dos servidores MySQL master (+1 backup) y dos servidores Redis.

Desde el propio Symfony nos describen como fue la implementación del proyecto Dailymotion.

Contras

No todo es de color de rosa. La curva de aprendizaje no es trivial. Deberás estar familiarizado con patrones y conceptos como Programación orientada a objetos (OOP), Modelo Vista Controlador (MVC), Inyección de dependencias (DI), Mapeador de objetos relacional (ORM), herramientas como Composer.

Trabajar con Doctine como ORM es muy productivo (desde el punto de vista del desarrollador). El poder acceder a las entidades hijas/padre de cualquier entidad y que se carguen solo cuando se accede a ellas, que se actualicen o borren en cascada, sin escribir nada de código (solo configurando los archivos .orm) es una maravilla, pero para llegar a tenerlo funcionando correctamente, antes tendrás que pelearte un poco para pillarle el truco a como se definen las relaciones 1 a N, y N a M (donde utilizar mappedBy e inversedBy. Recomiendo tener a mano esta ORM Cheatsheet). Además, si el modelo de base de datos ya lo tienes definido antes de empezar, te puedes encontrar con que a Doctrine no le gusta como se han creado las claves primarias, o las relaciones entre entidades, y obligarte a hacer cambios en el modelo.

En el entorno de producción exige que tengas instalado APC, OPCache, o algún otro acelerador de código PHP. Esto es bueno para tu aplicación. Te está obligando a tener una máquina donde va a rodar rápido, pero por contra, la instalación se hace más compleja, y necesitas tener cierto control sobre el Hosting donde la vayas a hospedar, así que tenlo en cuenta antes de contratar uno.

Si prevés que vas a tener un tráfico elevado, lo mejor será que tengas presente desde el principio el cacheado en memoria de las variables de sesión, consultas frecuentes a base de datos con baja variabilidad, renderizado de páginas enteras, etc. La integración de Symfony con Memcached y Redis es buena, pero como antes, necesitas que tu Hosting lo tenga disponible.

Conclusión

Symfony2 tiene todo lo necesario para poder abordar el desarrollo de una aplicación seria y de envergadura con garantías (como también otros frameworks), y después de un tiempo trabajando con él, puedo añadir que disfrutando mientras lo hacemos.

Desde este blog vamos a poner nuestro granito de arena para ayudaros a ponerlo a funcionar, con ejemplos prácticos reales que vayan algo más allá que un sencillo hola mundo, y compartir la experiencia de conocer esta potente herramienta.

¡¡ EMPEZAMOS !!


(1) Si ves que puedes aportar y mejorar una librería o Bundle que has encontrado, ¡¡ colabora !!. La inmensa mayoría son de código abierto, con sus repositorios en GitHub, gestionado por equipos entusiasmados por que otros desarrolladores participen.

¡¡ Hola mundo !!

Este blog ha sido creado para poder publicar mis experiencias en las diferentes fases del ciclo de vida del mundo del desarrollo, desde la toma de requisitos, o desarrollo de una idea, hasta el análisis, ejecución, pruebas, implantación, post-implantación y gestión del proyecto. A ver si sale algo interesante de todo esto. 🙂