Symfony 4: Un ejemplo práctico

Symfony 4 se publicará en Noviembre de 2017. Esta serie de artículos explica sus principales novedades:


¡Ha llegado la hora de probar Symfony 4! O al menos experimentar en primera persona cómo será programar aplicaciones Symfony 4 (aunque utilizando Symfony 3.3 por el momento). Las herramientas que vamos a ver todavía no son completamente estables, así que podrían cambiar en el futuro. De hecho, esperamos que nos comentéis todos los problemas que veáis y nos hagáis muchas sugerencias sobre nuevas funcionalidades.

La versión estable de Symfony Flex se publicará después del lanzamiento de Symfony 4 en noviembre de 2017. Así que la comunidad Symfony va a tener tiempo de sobra para discutir sobre posibles cambios en las funcionalidades presentadas en esta serie de artículos.

Además, Symfony Flex por el momento solo funciona con Symfony 3.3, que se publicará a finales de mayo de 2017. Para que sea más fácil trabajar con Symfony Flex antes del lanzamiento definitivo de Symfony 3.3, la opción minimum-stability del archivo composer.json del repositorio symfony/skeleton está puesta a dev. Así que no olvides utilizar versiones explícitas en tus otras dependencias o acabarás utilizando la versión master en todas ellas.

Creando un nuevo proyecto

El primer paso de esta demostración será crear un nuevo proyecto. Por ahora los proyectos se seguirán creando con el comando composer create-project, pero en el futuro podríamos utilizar alguna otra herramienta más sencilla y rápida:

$ composer create-project symfony/skeleton:3.3.x-dev demo
$ cd demo/

3.3 es la única versión disponible por el momento y corresponde a la próxima versión Symfony 3.3. Más adelante podrás usar versiones como 4.0, lts o latest, pero no antes de la fecha de lanzamiento de Symfony 4.0.

Este comando descarga el proyecto Symfony skeleton, cuyo único contenido es un archivo composer.json. Después, extrae el archivo en el directorio demo/ y ejecuta composer install automáticamente para descargar las dependencias del proyecto.

El paquete symfony/flex es el primero que se instala, para que así pueda intervenir en la instalación del resto de paquetes. Cuando Composer instala o actualiza cualquier dependencia del proyecto, Symfony Flex "se mete en medio" de ese proceso para hacer una petición al servidor de Symfony Flex preguntando si la dependencia define alguna "receta" en el repositorio de Symfony Flex (https://github.com/symfony/recipes y https://github.com/symfony/recipes-contrib). Si existe esa "receta", se ejecuta. De hecho, puedes ver a Symfony Flex en acción mirando los mensajes de log generados por Composer durante la instalación o actualización:

Mensajes de Symfony Flex en la consola

Cuando el proyecto se termina de instalar, verás un mensaje titulado What's Next que explica qué puedes hacer a continuación. Por ejemplo, puedes ejecutar el comando make serve para iniciar el servidor web interno de PHP. Antes de continuar, entra en el directorio del proyecto con cd demo/.

Mensaje después de crear el proyecto Symfony

El comando serve es una de las tareas que se han añadido en el Makefile del proyecto gracias a la "receta" definida por la dependencia symfony/framework- bundle.

Además, al final del proceso de creación del proyecto se han ejecutado algunos scripts:

Scripts ejecutados por Composer

Esos scripts se han añadido automáticamente al archivo composer.json del proyecto porque así lo define la receta del paquete symfony/framework-bundle. El segundo de los scripts definidos no se ha ejecutado porque por defecto los proyectos Symfony ya no tienen el script bin/console (que lo instala el paquete symfony/console).

Ahora que el proyecto ya está creado, podemos inicializarlo con Git:

$ git init
$ git add .
$ git commit -m "Creación del proyecto"

El comando git add . funciona como esperas porque Symfony ha creado el archivo .gitignore adecuado (de nuevo esto es debido a la "receta" de symfony/framework-bundle).

Aunque el proyecto symfony/skeleton solo tiene un archivo llamado composer.json, verás que en el directorio demo/ se han creado otros archivos y directorios. Esos archivos los ha creado Symfony Flex en función de las "recetas" definidas por los paquetes que se han instalado.

Examinemos la estructura de directorios. La mayoría de esos archivos se han añadido debido a la dependencia symfony/framework-bundle. El archivo .env en la raíz del proyecto define las variables de entorno APP_ENV y APP_DEBUG:

###> symfony/framework-bundle ###
APP_ENV=dev
APP_DEBUG=1
APP_SECRET=ODtvoHW6pn3bE2rHgTa2MjkjwefzlsJH
###< symfony/framework-bundle ###

Los comentarios ###> symfony/framework-bundle ### y ###< symfony/framework- bundle ### son necesarios para que Symfony Flex pueda añadir y eliminar contenidos en este archivo de forma segura. Así por ejemplo, si eliminas el paquete symfony/framework-bundle, sus variables de entorno se borran pero las demás no se ven afectadas. Así que no borres ni modifiques esos comentarios creados por Symfony Flex. El archivo .gitignore es un ejemplo parecido a .env y también incluye esos comentarios. Si eres una persona curiosa, no olvides echar un vistazo al nuevo controlador frontal del archivo public/index.php.

Los archivos más interesantes se encuentran en el directorio config/. Los principales puntos de entrada de la configuración son los archivos vacíos container.yaml y routing.yaml. Ahí es donde configuras los servicios, parámetros y rutas el proyecto. En el directorio config/packages/ se ha creado una configuración por defecto para el paquete symfony/framework-bundle. Puedes añadir cualquier otro archivo de configuración que necesites o hacer cualquier cambio en los archivos exsitentes.

Por último, el bundle FrameworkBundle se ha registrado automáticamente en bundles.php:

return [
    'Symfony\Bundle\FrameworkBundle\FrameworkBundle' => ['all' => true],
];

Aunque un bundle no tenga una "receta" definida, Symfony Flex detecta automáticamente si el archivo composer.json del paquete indica que es de tipo symfony-bundle. Si es así, se registra el bundle automáticamente en todos los entornos. Esto se hace para evitar tener que crear una receta cuando lo único que quieres es activar el bundle.

El directorio src/ es donde guardas el código PHP de tu aplicación. Todo ello bajo el namespace App\ (en vez de AppBundle\) que se define en composer.json. Además, este directorio es también donde se guarda el archivo Kernel.php (antes se guardaba en app/AppKernel.php).

Ha llegado el momento de instalar nuevas dependencias con Composer. Vamos a empezar instalando un servidor web local mejor que el make serve anterior:

$ composer req webserver

Y vamos a activar la consola de Symfony:

$ composer req cli

El comando req es un atajo de require (como Composer es una aplicación Symfony, cualquier comando se puede contraer siempre que no sea ambiguo). También puedes usar rem en vez de remove para eliminar paquetes.

El valor webserver es en realidad un alias del paquete symfony/web- server-bundle y cli es un alias de symfony/console. Symfony Flex sabe cómo convertir esos alias en los nombres completos de los paquetes. Si quieren, los paquetes pueden definir un número ilimitado de aliases: symfony/console define cli y console por ejemplo. Además, el prefijo symfony/ siempre es opcional. Prueba a ejecutar composer req workflow o composer req ldap y verás lo que pasa. Todo eso es para que la experiencia de uso sea increíble: teclear symfony/web-server-bundle es muy aburrido, web-server-bundle es un poco mejor, webserver es mejor y server es increíblemente mejor.

En el caso de los paquetes de Symfony, Flex soporta más versiones de las que utiliza Composer. En concreto, puedes usar las versiones next, previous, lts y stable (algunas no funcionan todavía, pero lo harán pronto).

$ composer req cli:next

Una vez instalado composer req cli, el comando assets:install se ejecuta automáticamente. Esto es debido a que ahora ya está disponible el script bin/console para ejecutar comandos de Symfony.

Scripts ejecutados por Symfony

Los alias también funcionan al eliminar paquetes:

$ composer rem cli

Si ejecutas el comando anterior, el archivo bin/console también se elimina. Si sientes curiosidad, prueba a eliminar el propio FrameworkBundle: composer rem framework-bundle.

Si recuerdas los artículos anteriores, una de los objetivos de Symfony Flex es ofrecer una experiencia de uso mejorada al instalar y usar bundles. Así que vamos a probar algo realmente "avanzado": instalar un admin generator basado en Doctrine. ¿Cuánto tiempo crees que nos va a costar instalar, configurar, activar y usar este bundle? Posiblemente menos de lo que imaginas.

En primer lugar, vamos a instalar EasyAdminBundle:

$ composer req admin

Además de instalar el propio admin generator, este comando instala todas sus dependencias y las configura automáticamente: TwigBundle, SecurityBundle, FrameworkExtraBundle y DoctrineBundle.

La palabra admin es muy genérica. Por eso en los artículo anteriores dijimos que íbamos a tomar decisiones sobre las "recetas" oficiales. Solo puede existir un paquete asociado al alias admin, otro paquete asociado con orm, etc.

Ahora ejecuta el servidor web de PHP con make serve o bin/console server:start y accede a la página http://localhost:8000/admin/. Deberías ver un mensaje de error porque no tienes todavía ninguna entidad de Doctrine. Vamos a crear una entidad muy simple en src/Entity/Product.php:

namespace App\Entity;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */
class Product
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;
 
    /**
     * @ORM\Column(type="string", length=100)
     */
    public $name;
 
    /**
     * @ORM\Column(type="decimal", scale=2)
     */
    public $price;
 
    /**
     * @ORM\Column(type="text")
     */
    public $description;
}

Ahora configura los datos de acceso de tu base de datos en el archivo .env:

###> doctrine/doctrine-bundle ###
DB_URL=mysql://[email protected]:3306/symfony?charset=utf8mb4
###< doctrine/doctrine-bundle ###

Ejecuta estos comandos para crear la base de datos:

$ ./bin/console doctrine:database:create
$ ./bin/console doctrine:schema:update --force

Por último, añade la entidad Product a la lista de entidades gestionadas por el admin generator:

# config/packages/easy_admin.yaml
easy_admin:
    entities:
        - App\Entity\Product

Carga de nuevo la página http://localhost:8000/admin/ y si todo ha funcionado bien, deberías ver un admin generator listo para gestionar los productos creados con esa entidad:

Interfaz de EasyAdmin

Otro ejemplo diferente al admin generator sería el que se muestra en este pequeño screencast donde se utiliza el alias api para crear una API muy rápida y fácilmente:

Estos son algunos de los alias que puedes probar:

  • sec-checker instalar el SensioLabs Security Checker para comprobar si tus dependencias tienen problemas de seguridad conocidos.
  • req-checker permite comprobar si tu ordenador cumple los requisitos para ejecutar aplicaciones Symfony.
  • log instala MonologBundle y sus dependencias.
  • template instala Twig.
  • mailer instala Swiftmailer.
  • profiler instala el profiler.

Como las aplicaciones Symfony ya no dependen de symfony/symfony, solo tienes las dependencias que realmente utilizas. Eso sí, como instalar las dependencias una a una puede llegar a ser muy aburrido, estamos probando una nueva idea llamada "packs". Un "pack" no es más que un repositorio Git que contiene un archivo composer.json con varios paquetes relacionados. Si quieres ver ejemplos prácticos, hemos creado el pack debug-pack que se puede instalar via composer req debug-pack y también el pack ORM pack y el pack API.

En el futuro podríamos crear un pack llamado web-pack que no tenga nada en el archivo composer.json, pero que esté asociado con una "receta" que instala una serie de archivos en el directorio public/, como un favicon, el archivo robots.txt, etc. ¿Ves cómo empiezan a encajar todas las piezas de esta nueva estrategia?

Más adelante crearemos "packs" para Travis, Docker, Blackfire, para crear algo parecido a la actual Symfony Standard Edition, etc. No hay límites a lo que vas a poder hacer con Symfony. Crea tus aplicaciones con paquetes de Composer y/o "packs" y/o "recetas". Symfony Flex es un nuevo paradigma: utiliza "composición" en vez de "herencia" al crear tus aplicaciones. Esta nueva forma de trabajar es más simple, más flexible y mucho más poderosa. Y esto es solo la primera versión del servidor Symfony Flex. Más adelante añadiremos muchas más opciones.

A estas alturas seguramente estás deseando ponerte a trastear con la aplicación Symfony 3.3 que has creado. ¿Qué tal si creas algún controlador y unas plantillas? No tan rápido. Aunque puedes seguir creando controladores como lo has hecho hasta ahora, las nuevas versiones de Symfony 3.3 y 4.0 proponen una forma mucho más cómoda de programar aplicaciones. Y ese será precisamente el tema del siguiente artículo.

Por último, recuerda que los repositorios de "recetas" son públicos, tanto el repositorio principal como el repositorio de la comunidad. Echa un vistazo para saber cómo crear tus propias recetas. Y no olvides que por ahora todo está en pruebas. Algunas cosas (y algunas decisiones) podrían cambiar.

Comentarios

Publicada el

2 de mayo de 2017

Etiquetas

Proyectos Symfony destacados

La plataforma de eCommerce 100% Symfony que rivaliza con Magento y PrestaShop. Ver más

Síguenos en @symfony_es para acceder a las últimas noticias.