Advertisement
  1. Code
  2. JavaScript

Configure el enrutamiento en aplicaciones PHP utilizando el componente de enrutamiento de Symfony

Scroll to top
Read Time: 10 min

() translation by (you can also view the original English article)

Hoy veremos el componente de enrutamiento de Symfony, que le permite configurar el enrutamiento en sus aplicaciones de PHP

¿Qué es el componente de enrutamiento de Symfony?

El componente de enrutamiento de Symfony es un componente de enrutamiento muy popular que está adaptado por varios sistemas y proporciona mucha flexibilidad en caso de que desee configurar rutas en su aplicación PHP.

Si ha creado una aplicación PHP personalizada y está buscando una biblioteca de enrutamiento rica en funciones, el Componente de enrutamiento de Symfony merece más que un vistazo. También le permite definir rutas para su aplicación en el formato YAML.

Comenzando con la instalación y la configuración, veremos ejemplos del mundo real para demostrar una variedad de opciones que tiene el componente para la configuración de rutas. En este artículo, aprenderá:

  • instalacion y configuracion
  • cómo configurar rutas básicas
  • cómo cargar rutas desde el archivo YAML
  • cómo usar el enrutador todo en uno

Instalacion y configuracion

En esta sección, vamos a instalar las bibliotecas que se requieren para configurar el enrutamiento en sus aplicaciones PHP. Supongo que ha instalado Composer en su sistema, ya que lo necesitaremos para instalar las bibliotecas necesarias que están disponibles en Packagist.

Una vez que haya instalado Composer, continúe e instale el componente Core Routing con el siguiente comando.

1
$composer require symfony/routing

Aunque el componente de enrutamiento en sí es suficiente para proporcionar funciones completas de enrutamiento en su aplicación, vamos a seguir adelante e instalar algunos otros componentes para facilitar nuestra vida y enriquecer la funcionalidad de enrutamiento básico existente.

Para empezar, procederemos e instalaremos el componente HttpFoundation, que proporciona un contenedor orientado a objetos para variables globales de PHP y funciones relacionadas con la respuesta. Se asegura de que no necesite acceder a variables globales como $ _GET, $ _POST y similares directamente.

1
$composer require symfony/http-foundation

A continuación, si quiere definir las rutas de su aplicación en el archivo YAML en lugar del código PHP, es el componente YAML el que lo rescata, ya que le ayuda a convertir cadenas YAML en matrices PHP y viceversa.

1
$composer require symfony/yaml

Finalmente, instalaremos el componente Config, que proporciona varias clases de utilidad para inicializar y tratar los valores de configuración definidos en los diferentes tipos de archivos como YAML, INI, XML, etc. En nuestro caso, lo usaremos para cargar rutas del archivo YAML.

1
$composer require symfony/config

Esa es la parte de la instalación, pero ¿cómo se supone que debes usarla? De hecho, solo se trata de incluir el archivo autoload.php creado por Composer en su aplicación, como se muestra en el siguiente fragmento.

1
<?php
2
require_once './vendor/autoload.php';
3
4
// application code

5
?>

Configurar rutas básicas

En la sección anterior, realizamos la instalación de los componentes de enrutamiento necesarios. Ahora, ya está listo para configurar el enrutamiento en su aplicación PHP de inmediato.

Avancemos y creemos el archivo basic_routes.php con los siguientes contenidos.

1
<?php
2
require_once './vendor/autoload.php';
3
4
use Symfony\Component\Routing\Matcher\UrlMatcher;
5
use Symfony\Component\Routing\RequestContext;
6
use Symfony\Component\Routing\RouteCollection;
7
use Symfony\Component\Routing\Route;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\Routing\Generator\UrlGenerator;
10
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
11
12
try
13
{
14
    // Init basic route

15
    $foo_route = new Route(
16
      '/foo',
17
      array('controller' => 'FooController')
18
    );
19
20
    // Init route with dynamic placeholders

21
    $foo_placeholder_route = new Route(
22
      '/foo/{id}',
23
      array('controller' => 'FooController', 'method'=>'load'),
24
      array('id' => '[0-9]+')
25
    );
26
27
    // Add Route object(s) to RouteCollection object

28
    $routes = new RouteCollection();
29
    $routes->add('foo_route', $foo_route);
30
    $routes->add('foo_placeholder_route', $foo_placeholder_route);
31
32
    // Init RequestContext object

33
    $context = new RequestContext();
34
    $context->fromRequest(Request::createFromGlobals());
35
36
    // Init UrlMatcher object

37
    $matcher = new UrlMatcher($routes, $context);
38
39
    // Find the current route

40
    $parameters = $matcher->match($context->getPathInfo());
41
42
    // How to generate a SEO URL

43
    $generator = new UrlGenerator($routes, $context);
44
    $url = $generator->generate('foo_placeholder_route', array(
45
      'id' => 123,
46
    ));
47
48
    echo '<pre>';
49
    print_r($parameters);
50
51
    echo 'Generated URL: ' . $url;
52
    exit;
53
}
54
catch (ResourceNotFoundException $e)
55
{
56
  echo $e->getMessage();
57
}

La configuración del enrutamiento utilizando el componente de enrutamiento de Symfony generalmente pasa por una serie de pasos como se detalla a continuación.

  • Inicialice el objeto de Route para cada una de sus rutas de aplicación.
  • Agregue todos los objetos de Route al objeto RouteCollection.
  • Inicialice el objeto RequestContext que contiene la información de contexto de solicitud actual.
  • Inicialice el objeto UrlMatcher pasando el objeto RouteCollection y el objeto RequestContext.

Inicializar el objeto de ruta para diferentes rutas

Avancemos y definamos una ruta de Foo bastante básica.

1
$foo_route = new Route(
2
  '/foo',
3
  array('controller' => 'FooController')
4
);

El primer argumento del constructor Route es la ruta URI, y el segundo argumento es la matriz de atributos personalizados que desea devolver cuando se hace coincidir esta ruta en particular. Normalmente, sería una combinación del controlador y el método al que desea llamar cuando se solicite esta ruta.

A continuación, echemos un vistazo a la ruta parametrizada.

1
$foo_placeholder_route = new Route(
2
  '/foo/{id}',
3
  array('controller' => 'FooController', 'method'=>'load'),
4
  array('id' => '[0-9]+')
5
);

La ruta anterior puede coincidir con URI como foo / 1, foo / 123 y similares. Tenga en cuenta que hemos restringido el parámetro {id} a valores numéricos solamente, y por lo tanto no coincidirá con los URI como foo / bar, ya que el parámetro {id} se proporciona como una cadena.

Agregar todos los objetos de ruta al objeto RouteCollection

El siguiente paso es agregar objetos de ruta que hemos inicializado en la sección anterior al objeto RouteCollection.

1
$routes = new RouteCollection();
2
$routes->add('foo_route', $foo_route);
3
$routes->add('foo_placeholder_route', $foo_placeholder_route);

Como puede ver, es bastante sencillo ya que solo necesita usar el método add del objeto RouteCollection para agregar objetos de ruta. El primer argumento del método add es el nombre de la ruta, y el segundo argumento es el objeto route.

Inicializar el objeto RequestContext

A continuación, necesitamos inicializar el objeto RequestContext, que contiene la información de contexto de solicitud actual. Necesitaremos este objeto cuando inicialicemos el objeto UrlMatcher, ya que lo revisaremos en un momento.

1
$context = new RequestContext();
2
$context->fromRequest(Request::createFromGlobals());

Inicializa el objeto UrlMatcher

Finalmente, necesitamos inicializar el objeto UrlMatcher junto con las rutas y la información de contexto.

1
// Init UrlMatcher object

2
$matcher = new UrlMatcher($routes, $context);

Ahora, tenemos todo lo que podemos combinar con nuestras rutas.

Cómo hacer coincidir las rutas

Es el método de Match del objeto UrlMatcher que le permite hacer coincidir cualquier ruta con un conjunto de rutas predefinidas.

El método de Match toma el URI como su primer argumento e intenta hacer coincidirlo con las rutas predefinidas. Si se encuentra la ruta, devuelve atributos personalizados asociados con esa ruta. Por otro lado, arroja la excepción ResourceNotFoundException si no hay ninguna ruta asociada con el URI actual.

1
$parameters = $matcher->match($context->getPathInfo());

En nuestro caso, proporcionamos el URI actual obteniéndolo del objeto $ context. Entonces, si está accediendo a la URL http: //your-domain/basic_routes.php/foo, $ context-> getPathInfo () devuelve foo, y ya hemos definido una ruta para el URI foo, por lo que debería devolvernos lo siguiente.

1
Array
2
(
3
    [controller] => FooController
4
    [_route] => foo_route
5
)

Ahora, vamos a probar la ruta parametrizada accediendo a la URL http: //your-domain/basic_routes.php/foo/123.

1
Array
2
(
3
    [controller] => FooController
4
    [method] => load
5
    [id] => 123
6
    [_route] => foo_placeholder_route
7
)

Funcionó si puede ver que el parámetro id está vinculado con el valor apropiado 123.

A continuación, intentemos acceder a una ruta inexistente como http: //your-domain/basic_routes.php/unknown-route, y debería ver el siguiente mensaje.

1
No routes found for "/unknown-route".

Así es como puedes encontrar rutas usando el método de Match.

Además de esto, también puede usar el componente de Routing para generar enlaces en su aplicación. Proporcionados objetos RouteCollection y RequestContext, el UrlGenerator le permite construir enlaces para rutas específicas.

1
$generator = new UrlGenerator($routes, $context);
2
$url = $generator->generate('foo_placeholder_route', array(
3
  'id' => 123,
4
));

El primer argumento del método generate es el nombre de la ruta, y el segundo argumento es la matriz que puede contener parámetros si se trata de la ruta parametrizada. El código anterior debe generar la URL /basic_routes.php/foo/123.

Cargar rutas desde el archivo YAML

En la sección anterior, construimos nuestras rutas personalizadas utilizando los objetos Route y RouteCollection. De hecho, el componente Routing ofrece diferentes formas de elegir entre crear instancias de rutas. Puede elegir entre varios cargadores como YamlFileLoader, XmlFileLoader y PhpFileLoader.

En esta sección, revisaremos el cargador YamlFileLoader para ver cómo cargar rutas desde el archivo YAML.

El archivo YAML de Rutas

Continúa y crea el archivo routes.yaml con los siguientes contenidos.

1
foo_route:
2
    path:     /foo
3
    defaults: { controller: 'FooController::indexAction' }
4
5
foo_placeholder_route:
6
    path:     /foo/{id}
7
    defaults: { controller: 'FooController::loadAction' }
8
    requirements:
9
        id: '[0-9]+'

Un archivo de ejemplo

A continuación, siga adelante y cree el archivo load_routes_from_yaml.php con los siguientes contenidos.

1
<?php
2
require_once './vendor/autoload.php';
3
4
use Symfony\Component\Routing\Matcher\UrlMatcher;
5
use Symfony\Component\Routing\RequestContext;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Component\Routing\Generator\UrlGenerator;
8
use Symfony\Component\Config\FileLocator;
9
use Symfony\Component\Routing\Loader\YamlFileLoader;
10
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
11
12
try
13
{
14
    // Load routes from the yaml file

15
    $fileLocator = new FileLocator(array(__DIR__));
16
    $loader = new YamlFileLoader($fileLocator);
17
    $routes = $loader->load('routes.yaml');
18
19
    // Init RequestContext object

20
    $context = new RequestContext();
21
    $context->fromRequest(Request::createFromGlobals());
22
23
    // Init UrlMatcher object

24
    $matcher = new UrlMatcher($routes, $context);
25
26
    // Find the current route

27
    $parameters = $matcher->match($context->getPathInfo());
28
29
    // How to generate a SEO URL

30
    $generator = new UrlGenerator($routes, $context);
31
    $url = $generator->generate('foo_placeholder_route', array(
32
      'id' => 123,
33
    ));
34
35
    echo '<pre>';
36
    print_r($parameters);
37
38
    echo 'Generated URL: ' . $url;
39
    exit;
40
}
41
catch (ResourceNotFoundException $e)
42
{
43
  echo $e->getMessage();
44
}

¡Lo único que es diferente en este caso es la forma en que iniciamos las rutas!

1
$fileLocator = new FileLocator(array(__DIR__));
2
$loader = new YamlFileLoader($fileLocator);
3
$routes = $loader->load('routes.yaml');

Hemos utilizado el cargador YamlFileLoader para cargar rutas desde el archivo routes.yaml en lugar de inicializarlo directamente en el PHP. Aparte de eso, todo es igual y debería producir los mismos resultados que el del archivo basic_routes.php.

El enrutador todo en uno

Por último, en esta sección, examinaremos la clase Router, que le permite configurar el enrutamiento rápidamente con menos líneas de código.

Continúa y crea el archivo all_in_one_router.php con los siguientes contenidos.

1
<?php
2
require_once './vendor/autoload.php';
3
4
use Symfony\Component\Routing\RequestContext;
5
use Symfony\Component\Routing\Router;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Component\Routing\Generator\UrlGenerator;
8
use Symfony\Component\Config\FileLocator;
9
use Symfony\Component\Routing\Loader\YamlFileLoader;
10
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
11
12
try
13
{
14
    $fileLocator = new FileLocator(array(__DIR__));
15
16
    $requestContext = new RequestContext();
17
    $requestContext->fromRequest(Request::createFromGlobals());
18
19
    $router = new Router(
20
        new YamlFileLoader($fileLocator),
21
        'routes.yaml',
22
        array('cache_dir' => __DIR__.'/cache'),
23
        $requestContext
24
    );
25
26
    // Find the current route

27
    $parameters = $router->match($requestContext->getPathInfo());
28
29
    // How to generate a SEO URL

30
    $routes = $router->getRouteCollection();
31
    $generator = new UrlGenerator($routes, $requestContext);
32
    $url = $generator->generate('foo_placeholder_route', array(
33
      'id' => 123,
34
    ));
35
36
    echo '<pre>';
37
    print_r($parameters);
38
39
    echo 'Generated URL: ' . $url;
40
    exit;
41
}
42
catch (ResourceNotFoundException $e)
43
{
44
  echo $e->getMessage();
45
}

Todo es prácticamente igual, excepto que hemos creado una instancia del objeto Router junto con las dependencias necesarias.

1
$router = new Router(
2
    new YamlFileLoader($fileLocator),
3
    'routes.yaml',
4
    array('cache_dir' => __DIR__.'/cache'),
5
    $requestContext
6
);

Con eso en su lugar, puede usar directamente el método de match del objeto Router para el mapeo de ruta.

1
$parameters = $router->match($requestContext->getPathInfo());

Además, deberá usar el método getRouteCollection del objeto Router para buscar rutas.

1
$routes = $router->getRouteCollection();

Conclusión

Continúe y explore las otras opciones disponibles en el componente Enrutamiento: ¡me encantaría escuchar sus pensamientos!

Hoy, exploramos el componente de enrutamiento de Symfony, que hace que la implementación del enrutamiento en aplicaciones PHP sea muy sencilla. En el camino, creamos un puñado de ejemplos para demostrar diversos aspectos del componente Enrutamiento.

Espero que hayas disfrutado este artículo, y no dudes en publicar tus comentarios utilizando el feed a continuación.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.