¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí

La primera aplicacion

La estructura de Symfony

Toda la aplicación se desarrollará en el directorio src. Aquí es donde escribiremos todo el código.

El framework Symfony utiliza una estructura bien conocida: la estructura MVC. MVC significa: Modelo, Vista, Controlador.

Detallemos un poco estos tres elementos de la estructura.

  • Los modelos agrupan todos los datos que utiliza su aplicación. Estos pueden ser datos de bases de datos, pero no exclusivamente. Los datos pueden provenir de diferentes fuentes e incluso ser el resultado de cálculos matemáticos. A menudo se dice que el modelo es el núcleo del negocio. Es el material con el que trabaja. Veremos más adelante dónde instalar los modelos. También veremos cómo usar Doctrine, el gestor de bases de datos de Symfony.

  • Las vistas agrupan todo lo que generan las páginas HTML finales visibles para el usuario. Estas vistas están todas reunidas en la carpeta templates, que se encuentra en la raíz de su aplicación. Las vistas no son archivos PHP, sino archivos Twig. Twig es un lenguaje de plantillas; volveremos a esto más adelante.

  • Los controladores agrupan todos los programas PHP que coordinarán su aplicación. Son ellos quienes llamarán a los modelos necesarios y, al final, llamarán a las vistas que se devolverán. Comenzaremos explorando los controladores, ya que son el corazón de su aplicación....

Los controladores

Todos los controladores se crearán en la subcarpeta: src/Controller. Por ahora, esta carpeta está vacía.

  • Los controladores son clases contenidas en un archivo con el mismo nombre.

  • Todos los nombres de controladores terminan con Controller (por ejemplo, HomeController). Preste atención a las mayúsculas, ya que son importantes: cada palabra comienza con mayúscula y no hay separadores.

  • Es posible crear un controlador manualmente, pero lo mejor es utilizar la consola de Symfony en línea de comandos.

Creemos, por ejemplo, un controlador TestController para probar nuestra aplicación. En la ventana del terminal, escriba el siguiente comando:

php bin/console make:controller TestController 

Es posible que obtenga el siguiente error:

images/10RIT01.png

En este caso, su instalación no ha integrado una biblioteca llamada Symfony MakerBundle. Por supuesto, debe usar Composer para instalarla:

composer require symfony/maker-bundle --dev 

La opción --dev integrará esta biblioteca en la etiqueta require-dev del archivo composer.json. Podremos eliminar esta etiqueta en modo de producción. 

 Asegúrese también de estar en modo dev en el archivo .env:

 APP_ENV=dev 

 Vuelva a ejecutar el comando:

php bin/console make:controller TestController 

Esta vez, debería salir bien.

El controlador TestController se crea en la carpeta src/Controller. Examinemos el código...

Las vistas

La vista es el archivo final que genera la página destinada a ser visualizada por el usuario.

Está compuesta de HTML, CSS, JavaScript y todos los elementos que serán interpretados por el navegador del cliente.

La vista también puede contener pequeñas instrucciones de un lenguaje de plantillas llamado Twig. Este lenguaje permite realizar operaciones en la vista tal y como lo haríamos en una página PHP. Por ejemplo, Twig permite definir variables, hacer bucles, colocar instrucciones condicionales, pero de una manera mucho más sencilla que con PHP. El objetivo es separar la parte de desarrollo en PHP de la parte front en HTML, CSS...

Así, alguien que domine Twig no necesita desarrollar en PHP para implementar el diseño del sitio.

Todas las vistas se almacenan en la carpeta templates de la aplicación. Actualmente, la carpeta templates contiene una subcarpeta llamada test que se ha generado al crear el controlador TestController. Contiene la vista index.html.twig.

Observamos la presencia de otro archivo: base.html.twig, en la carpeta templates. Esto es lo que llamamos un layout. Es una vista que servirá de esqueleto a otras vistas (ver capítulo El motor de plantillas Twig).

Abramos el archivo templates/test/index.html.twig y examinemos el código:

{% extends 'base.html.twig' %}  
  
{% block title %}Hello...

El directorio public

Este es el único directorio accesible por la solicitud del cliente. Contiene todos los archivos que pueden cargarse en el navegador del usuario.

En caso necesario, es importante dar permiso de lectura a este directorio (con la nueva versión de Symfony, ya no hay problemas a este respecto).

Encontraremos el CSS para los estilos de la página, el JavaScript para las animaciones, las imágenes y, en general, todos los medios y archivos accesibles para el usuario. Sí, todos estos archivos se colocan aquí y no en el directorio templates.

Aquí también es donde se encuentra el punto de entrada de la aplicación, el famoso archivo index.php.

Todas las peticiones del usuario, por ejemplo, localhost:8000/test, solo acceden a este archivo. El controlador será el encargado de dirigir el flujo de la ejecución. 

No modificaremos este archivo, salvo en contadas excepciones.

El directorio var

Este directorio contiene dos subdirectorios, cache y logs.

Symfony guarda varios archivos en caché con cada solicitud. El subdirectorio cache contiene todos los archivos en caché generados por la aplicación.

Será necesario vaciar regularmente la caché, sobre todo para tener en cuenta las actualizaciones del código. Se puede eliminar manualmente los subdirectorios del directorio cache, como, por ejemplo, el subdirectorio dev.

También hay un comando de consola para hacerlo:

php bin/console cache:clear 

Si no ve el resultado al modificar el código, probablemente se deba a la caché. Recuerde vaciarla regularmente.

El directorio vendor

Este es el directorio que contiene todas las bibliotecas utilizadas por Symfony. Se genera con Composer durante la instalación. Como hemos visto, es Composer quien se encarga de instalar todas las bibliotecas necesarias. Composer crea un directorio vendor e instala las bibliotecas en su interior. También crea un archivo autoload.php, que permitirá hacer referencia a estas bibliotecas en el código mediante el espacio de nombres (namespace).

En ningún momento debe modificar manualmente el contenido del directorio vendor. Este debería contener la última versión de las bibliotecas instaladas. Si se instala una nueva biblioteca con Composer, se añadirá en este directorio. Cada actualización de Symfony sobrescribirá el contenido de este directorio.

Otros archivos de la aplicación

Volveremos más adelante sobre los otros directorios que componen la aplicación. No es difícil imaginar que el directorio translations contendrá los posibles archivos de traducción en caso de un sitio multilingüe, y que el directorio test permitirá definir pruebas para nuestra aplicación.

También encontrará el directorio bin, que contiene el archivo console, el cual permite ejecutar comandos en la línea de comandos. Este archivo está en PHP, lo que significa que también podríamos ejecutar la consola directamente en un navegador.

El directorio bin también contiene un archivo phpunit utilizado para realizar pruebas.

Finalmente, en la raíz de la aplicación, además de .env y .env.test, encontrará los archivos «composer.json» y «composer.lock», que bloquea las versiones de las bibliotecas instaladas. También encontrará algunos otros archivos (phpunit.xml.dist, symfony.lock...).

Y con esto ya hemos hecho una presentación general de la estructura de Symfony.

Los componentes de HttpFoundation

Todo acceso a una aplicación web se realiza mediante una solicitud HTTP. Sin entrar en detalles, una solicitud HTTP se compone de una cabecera, que contiene información (como, por ejemplo: el nombre de dominio del sitio, el tipo de contenido transmitido...), y de un cuerpo (body), en el que se envían los parámetros que hay que transmitir.

La respuesta del servidor después de ejecutar la solicitud tiene la misma sintaxis. También contiene una cabecera que especifica una serie de información y el código HTML de la respuesta que será interpretado por el navegador.

Estos dos elementos, con toda su información, se traducen en Symfony mediante componentes de la biblioteca HttpFoundation. Estos componentes son dos clases existentes: la clase Request y la clase Response. Consulte el capítulo Lenguaje orientado a objetos, sección Las clases, si ha olvidado la noción de clase.

El uso de estas dos clases Request y Response es muy práctico, ya que podemos encontrar fácilmente los parámetros de la solicitud transmitida o definir los parámetros de la respuesta transmitida.

Pero ¿cómo acceder a estas dos clases de Symfony?

Es posible acceder a ellas utilizando su espacio de nombres correspondiente:

 <?php  
use Symfony\Component\HttpFoundation\Request;  
use Symfony\Component\HttpFoundation\Response;...

El objeto Request

Hablaremos del objeto Request, aunque esto no sea del todo exacto. En realidad, se trata de un objeto instanciado a partir de la clase Request.

Para usar el objeto Request en una acción, es necesario transmitir este objeto en los parámetros de la acción.

Tomemos como ejemplo la acción index() del controlador TestController. Para usar el objeto Request, primero debemos declarar su espacio de nombres:

use Symfony\Component\HttpFoundation\Response; 

luego, puede usar el objeto $request con la inyección de dependencias en el método index:

use Symfony\Component\HttpFoundation\Request;  
class TestController extends AbstractController   
{   
        #[Route('/test', name: 'app_test')]  
        public function index(Request $request)   
        {... } 

Este uso puede parecer extraño al principio.

¿Cómo se instancia el objeto $request?

El objeto $request se instancia automáticamente porque está precedido por el nombre de la clase Request. Symfony se encarga de todo.

Dentro de la acción, tiene toda la libertad para consultar este objeto $request. Por ejemplo, para obtener el nombre de la solicitud, puede usar el método getPathInfo().

Puede probar este método incluyendo el siguiente código en su controlador TestController:

<?php  
  
namespace App\Controller;  ...

El objeto Response

Ahora es el turno de los objetos instanciados a partir de la clase Response.

El objeto Response define la respuesta que se enviará al navegador del cliente.

A diferencia del objeto Request, debe instanciarse dentro de la acción del controlador. He aquí un ejemplo de uso del objeto Response:

<?php  
  
namespace App\Controller;  
use Symfony\Component\HttpFoundation\Request;  
use Symfony\Component\HttpFoundation\Response;  
  
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;  
use Symfony\Component\Routing\Annotation\Route;  
  
class TestController extends AbstractController  
{  
    /**  
     * @Route("/test", name="test")  
     */  
    public function index(Request $request)  
    {  
          
        $reponse=new Response('Bienvenido a Symfony');   
        return $reponse;   
    }  
} 

La acción index() devuelve la respuesta, que seguirá su curso para ser transformada en una respuesta HTTP. Esta vez, no necesitamos el método render(), que hace referencia a una página Twig.

Una función de tipo acción debe devolver obligatoriamente un objeto de la clase Response.

Al ejecutar la solicitud localhost:8000/test, obtendrá la siguiente visualización:

images/10RIT07.png

¿Qué ocurre cuando la acción llama a una vista Twig?

Es el método $this->render(...) el que genera el objeto Response enviado.

Por lo tanto, una acción siempre devuelve un objeto Response. Atención: si omite devolver este objeto Response, obtendrá un error de Symfony. El tipado impone que todas las acciones del controlador devuelvan un objeto de tipo Response.

El método $this->render se encuentra en la clase AbstractController. Al consultar...

Las variables de sesión

1. La utilidad de las variables de sesión

Cuando un cliente realiza una solicitud HTTP, esta es recibida por el servidor, que la procesa y envía una respuesta al navegador del cliente.

Cada solicitud es independiente de las demás.

No hay información que persista de una solicitud a otra. Los parámetros y todo lo que envíe al servidor solo pueden utilizarse en la solicitud que los contiene.

A veces es necesario conservar información específica del cliente que está conectado. Por ejemplo, si su cliente realiza un pedido de productos, sería útil conservar el estado de su carrito de compras de una solicitud a otra.

Este estado es específico para cada cliente. Incluso si la información se guarda en el servidor (por ejemplo, en una base de datos), es necesario identificar la que corresponde al cliente conectado.

Para ello, el servidor envía un identificador de sesión, que se almacena en el navegador de cada cliente (es una cookie). Con este identificador, puede identificar al cliente cada vez que se conecta y mostrarle su carrito de compras.

images/10RIT10.png

El almacenamiento de este identificador de sesión dura mientras el navegador está abierto y desaparece al cerrar el navegador. Si el cliente se vuelve a conectar, deberá solicitar un nuevo identificador. Esta volatilidad del identificador de sesión evita posibles vulnerabilidades de seguridad, como el robo del identificador de sesión.

2. El uso de variables de sesión en Symfony

Las variables de sesión se gestionan a partir del objeto $request. Es necesario solicitar la apertura de una sesión con la instrucción:

 $sesion = $request->getSession(); 

Es posible crear una o varias variables de sesión. Estas variables se identificarán como propias del cliente gracias al identificador de sesión generado:

 $miVariable...