¿Qué es una ruta URI?

Antes de sumergirse en los controladores y rutas en CodeIgniter, hay que conocer el enrutamiento URI.

Este asocia un URI con el método de un controlador. A su vez, CodeIgniter tiene dos tipos de enrutamiento: uno es enrutamiento de ruta definida y el otro es enrutamiento automático.

  • Con el enrutamiento de ruta definida se puede definir rutas manualmente. También permite URL flexible
  • El enrutamiento automático, como bien dice su nombre, enruta automáticamente las solicitudes HTTP. Esto de acuerdo a las convenciones y ejecuta los métodos de controlador correspondientes. No hay necesidad de definir rutas manualmente.

Configuración de reglas de enrutamiento

Las reglas de enrutamiento se definen en el archivo app/Config/Routes.php. En él verás que crea una instancia de la clase RouteCollection ($routes) que te permite especificar tus propios criterios de enrutamiento. Las rutas se pueden especificar mediante marcadores de posición o expresiones regulares.

Cuando especifica una ruta, elige un método correspondiente a los verbos HTTP (método de solicitud). Si espera una solicitud GET, utilice el método get():

<?php

$routes->get('/', 'Home::index');

Una ruta toma la ruta URI (/) a la izquierda y la asigna al controlador y al método (Home::index) a la derecha, junto con los parámetros que deben pasarse al controlador. El controlador y el método deben enumerarse de la misma manera que usaría un método estático, separando la clase y su método con dos puntos, como Users::list.

Si ese método requiere que se le pasen parámetros, se enumerarán después del nombre del método, separados por barras diagonales:

<?php

// Calls $Users->list()
$routes->get('users', 'Users::list');

// Calls $Users->list(1, 23)
$routes->get('users/1/23', 'Users::list/1/23');
Puede usar cualquier verbo HTTP estándar (GET, POST, PUT, DELETE, etc.):
<?php

$routes->post('products', 'Product::feature');
$routes->put('products/1', 'Product::feature');
$routes->delete('products/1', 'Product::feature');

Puede proporcionar varios verbos con los que debe coincidir una ruta pasándolos como una matriz al match() método:

<?php

$routes->match(['get', 'put'], 'products', 'Product::feature');

Espacio de nombres del controlador

Si se establece un nombre de controlador sin comenzar con \, se agregará el espacio de nombres predeterminado:

<?php

// Routes to \App\Controllers\Api\Users::update()
$routes->post('api/users', 'Api\Users::update');

Si lo pone \ al principio, se trata como un nombre de clase completo:

<?php

// Routes to \Acme\Blog\Controllers\Home::list()
$routes->get('blog', '\Acme\Blog\Controllers\Home::list');

También puede especificar el espacio de nombres con la opción namespace:

<?php

// Routes to \Admin\Users::index()
$routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']);

Consulte Asignación de espacio de nombres para obtener más información.

Marcadores de posición

Una ruta típica podría verse así:

<?php

$routes->get('product/(:num)', 'Catalog::productLookup');

En una ruta, el primer parámetro contiene el URI que debe coincidir, mientras que el segundo parámetro contiene el destino al que debe enrutarse. En el ejemplo anterior, si la palabra literal “producto” se encuentra en el primer segmento de la ruta de la URL y se encuentra un número en el segundo segmento, se utilizan la clase Catalog y el método productLookup en su lugar.

Los marcadores de posición son simplemente cadenas que representan un patrón de expresión regular. Durante el proceso de enrutamiento, estos marcadores de posición se reemplazan con el valor de la expresión regular. Se utilizan principalmente para la legibilidad.

Los siguientes marcadores de posición están disponibles para que los use en sus rutas:

Marcadores de posición Descripción
(:ningún) Coincidirá con todos los caracteres desde ese punto hasta el final del URI. Esto puede incluir varios segmentos de URI.
(:segmento) Coincidirá con cualquier carácter excepto una barra inclinada ( /) que restringe el resultado a un solo segmento.
(:numero) Coincidirá con cualquier número entero.
(:alfa) Coincidirá con cualquier cadena de caracteres alfabéticos.
(:alfanum) Coincidirá con cualquier cadena de caracteres alfabéticos o enteros, o cualquier combinación de los dos.
(:picadillo) Es lo mismo que (:segment), pero se puede usar para ver fácilmente qué rutas usan identificadores hash.

Ejemplos

Una URL que contenga la palabra journals en el primer segmento se asignará a la clase \App\Controllers\Blogs y al método predeterminado, que suele ser index():

<?php

$routes->get('journals', 'Blogs');

Se asignará una URL que contenga los segmentos blog/joe a la \App\Controllers\Blogs clase y al  método users(). El ID se establecerá en 34:

<?php

$routes->get('blog/joe', 'Blogs::users/34');

Una URL con producto como primer segmento y cualquier cosa en el segundo se asignará a la clase \App\Controllers\Catalog y el método productLookup():

<?php

$routes->get('product/(:any)', 'Catalog::productLookup');

Una URL con producto como primer segmento y un número en el segundo se asignará a la clase\App\Controllers\Catalog y el método productLookupByID()  pasará la coincidencia como una variable al método:

<?php

$routes->get('product/(:num)', 'Catalog::productLookupByID/$1');

Tenga en cuenta que un solo (:any) coincidirá con múltiples segmentos en la URL si está presente. Por ejemplo la ruta:

<?php

$routes->get('product/(:any)', 'Catalog::productLookup/$1');

Coincidirá con product/123 , product/123/456 , product/123/456/789 y así sucesivamente. La implementación en el Controller debe tener en cuenta los parámetros máximos:

<?php

namespace App\Controllers;

class ProductController extends BaseController
{
public function productLookup($seg1 = false, $seg2 = false, $seg3 = false)
{
echo $seg1; // Will be 123 in all examples
echo $seg2; // false in first, 456 in second and third example
echo $seg3; // false in first and second, 789 in third
}
}

Si la coincidencia de varios segmentos no es el comportamiento previsto, (:segment) se debe utilizar al definir las rutas. Con los ejemplos de URL de arriba:

<?php

$routes->get('product/(:segment)', 'Catalog::productLookup/$1');

Solo coincidirá con producto/123 y generará errores 404 para otro ejemplo.

Sintaxis invocable de matriz

Desde v4.2.0, puede usar la sintaxis invocable de matriz para especificar el controlador:

$routes->get('/', [\App\Controllers\Home::class, 'index']);

O usando use la palabra clave:

use App\Controllers\Home;

$routes->get('/', [Home::class, 'index']);

Si hay marcadores de posición, establecerá automáticamente los parámetros en el orden especificado:

use App\Controllers\Product;

$routes->get('product/(:num)/(:num)', [Product::class, 'index']);

// The above code is the same as the following:
$routes->get('product/(:num)/(:num)', 'Product::index/$1/$2');

Pero los parámetros configurados automáticamente pueden no ser correctos si usa expresiones regulares en las rutas. En tal caso, puede especificar los parámetros manualmente:

use App\Controllers\Product;

$routes->get('product/(:num)/(:num)', [[Product::class, 'index'], '$2/$1']);

// The above code is the same as the following:
$routes->get('product/(:num)/(:num)', 'Product::index/$2/$1');

Marcadores de posición personalizados

Puede crear sus propios marcadores de posición que se pueden usar en su archivo de rutas para personalizar completamente la experiencia y la legibilidad.

Agrega nuevos marcadores de posición con el método addPlaceholder(). El primer parámetro es la cadena que se utilizará como marcador de posición. El segundo parámetro es el patrón de expresión regular por el que debe reemplazarse. Esto debe llamarse antes de agregar la ruta:

<?php

$routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}');
$routes->get('users/(:uuid)', 'Users::show/$1');

Expresiones regulares

Si lo prefiere, puede utilizar expresiones regulares para definir sus reglas de enrutamiento. Se permite cualquier expresión regular válida, al igual que las referencias anteriores.

En el ejemplo anterior, un URI similar a productos/camisas/123 llamaría al show método de la clase de controlador, con el primer y segundo segmento originales pasados ​​como argumentos. Con las expresiones regulares, también puede captar un segmento que contenga una barra diagonal (/), que normalmente representaría el delimitador entre varios segmentos.

Por ejemplo, si un usuario accede a un área protegida por contraseña de su aplicación web y desea poder redirigirlo a la misma página después de iniciar sesión, este ejemplo le puede resultar útil:

<?php

$routes->get('login/(.+)', 'Auth::login/$1');

Para aquellos de ustedes que no conocen las expresiones regulares y quieren aprender más sobre ellas, regular-expressions.info puede ser un buen punto de partida.

Cierres

Puede usar una función anónima, o Cierre, como el destino al que se asigna una ruta. Esta función se ejecutará cuando el usuario visite esa URI. Esto es útil para ejecutar rápidamente tareas pequeñas, o incluso para mostrar una vista simple:

<?php

$routes->get('feed', static function () {
$rss = new RSSFeeder();

return $rss->feed('general');
});

Mapeo de múltiples rutas

Si bien el método add() es simple de usar, a menudo es más práctico trabajar con varias rutas a la vez, utilizando el método map(). En lugar de llamar al método add() para cada ruta que necesite agregar, puede definir una matriz de rutas y luego pasarla como el primer parámetro al map() método:

<?php

$multipleRoutes = [
'product/(:num)' => 'Catalog::productLookupById',
'product/(:alphanum)' => 'Catalog::productLookupByName',
];

$routes->map($multipleRoutes);

Redirección de rutas

Cualquier sitio que viva lo suficiente seguramente tendrá páginas que se muevan. Puede especificar rutas que deberían redirigir a otras rutas con el método addRedirect(). El primer parámetro es el patrón de URI para la ruta anterior.

El segundo parámetro es el nuevo URI al que se redirigirá o el nombre de una ruta con nombre. El tercer parámetro es el código de estado HTTP que debe enviarse junto con la redirección. El valor predeterminado es 302, que es una redirección temporal y se recomienda en la mayoría de los casos:

<?php

$routes->get('users/profile', 'Users::profile', ['as' => 'profile']);

// Redirect to a named route
$routes->addRedirect('users/about', 'profile');
// Redirect to a URI
$routes->addRedirect('users/about', 'users/profile');

// Redirect with placeholder
$routes->get('post/(:num)/comment/(:num)', 'PostsComments::index', ['as' => 'post.comment']);

// Redirect to a URI
$routes->addRedirect('article/(:num)/(:num)', 'post/$1/comment/$2');
// Redirect to a named route
$routes->addRedirect('article/(:num)/(:num)', 'post.comment');

Si una ruta de redirección coincide durante la carga de una página, el usuario será redirigido inmediatamente a la nueva página antes de que se pueda cargar un controlador.

Agrupación de rutas

Puede agrupar sus rutas bajo un nombre común con el método group(). El nombre del grupo se convierte en un segmento que aparece antes de las rutas definidas dentro del grupo. Esto le permite reducir la escritura necesaria para crear un amplio conjunto de rutas que comparten la cadena de apertura, como cuando se crea un área de administración:

<?php

$routes->group('admin', static function ($routes) {
$routes->get('users', 'Admin\Users::index');
$routes->get('blog', 'Admin\Blog::index');
});

Esto prefijaría los URI de usuarios y blogs con admin , manejando URL como admin/users y admin/blog.

Si necesita asignar opciones a un grupo, como Asignación de espacio de nombres, hágalo antes de la devolución de llamada:

<?php

$routes->group('api', ['namespace' => 'App\API\v1'], static function ($routes) {
$routes->resource('users');
});

Esto manejaría una ruta de recursos al App\API\v1\Users controlador con el URI api/users.
También puede utilizar un filtro específico para un grupo de rutas. Esto siempre ejecutará el filtro antes o después del controlador. Esto es especialmente útil durante la autenticación o el registro de API:

<?php

$routes->group('api', ['filter' => 'api-auth'], static function ($routes) {
$routes->resource('users');
});

El valor del filtro debe coincidir con uno de los alias definidos en app/Config/Filters.php.

Es posible anidar grupos dentro de grupos para una mejor organización si lo necesita:

<?php

$routes->group('admin', static function ($routes) {
$routes->group('users', static function ($routes) {
$routes->get('list', 'Admin\Users::list');
});
});

Esto manejaría la URL en admin/users/list.

En algún momento, es posible que desee agrupar rutas con el fin de aplicar filtros u otras opciones de configuración de ruta, como espacio de nombres, subdominio, etc. Sin necesidad de agregar necesariamente un prefijo al grupo, puede pasar una cadena vacía en lugar del prefijo y las rutas en el grupo se enrutarán como si el grupo nunca hubiera existido pero con las opciones de configuración de ruta dadas:

<?php

$routes->group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) {
$routes->get('login', 'AuthController::login', ['as' => 'login']);
$routes->post('login', 'AuthController::attemptLogin');
$routes->get('logout', 'AuthController::logout');
});

Restricciones

Puede crear un conjunto de rutas que solo se podrán ver en un determinado entorno. Esto le permite crear herramientas que solo el desarrollador puede usar en sus máquinas locales a las que no se puede acceder en los servidores de prueba o producción. Esto se puede hacer con el método environment(). El primer parámetro es el nombre del entorno. Las rutas definidas dentro de este cierre solo son accesibles desde el entorno dado:
<?php

$routes->environment('development', static function ($routes) {
$routes->get('builder', 'Tools\Builder::index');
});

Enrutamiento inversoEl enrutamiento inverso le permite definir el controlador y el método, así como cualquier parámetro, al que debe ir un enlace y hacer que el enrutador busque la ruta actual. Esto permite que las definiciones de ruta cambien sin tener que actualizar el código de su aplicación. Esto se usa normalmente dentro de las vistas para crear enlaces.

Por ejemplo, si tiene una ruta a una galería de fotos a la que desea vincular, puede usar la función url_to() de ayuda para obtener la ruta que debe usarse. El primer parámetro es el controlador y el método completamente calificados, separados por dos puntos dobles (::), muy parecidos a los que usaría al escribir la ruta inicial. Cualquier parámetro que deba pasarse a la ruta se pasa a continuación:

<?php

// The route is defined as:
$routes->get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2');

?>

<!-- Generate the URI to link to user ID 15, gallery 12: -->
<a href="<?= url_to('Galleries::showUserGallery', 15, 12) ?>">View Gallery</a>
<!-- Result: 'http://example.com/users/15/gallery/12' -->

Uso de rutas con nombre

Puede nombrar rutas para que su aplicación sea menos frágil. Esto aplica un nombre a una ruta que se puede llamar más tarde, e incluso si la definición de la ruta cambia, todos los enlaces en su aplicación route_to() seguirán funcionando sin que tenga que hacer ningún cambio. Una ruta se nombra pasando la opción as con el nombre de la ruta:

<?php

// The route is defined as:
$routes->get('users/(:num)/gallery(:any)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']);

?>

<!-- Generate the URI to link to user ID 15, gallery 12: -->
<a href="<?= url_to('user_gallery', 15, 12) ?>">View Gallery</a>
<!-- Result: 'http://example.com//users/15/gallery/12' -->

Esto tiene el beneficio adicional de hacer que las vistas también sean más legibles.

Rutas con verbos HTTP

Es posible definir una ruta con HTTP. Puedes usar el método add():

<?php

$routes->add('products', 'Product::feature');

Rutas solo de línea de comandos

Puede crear rutas que funcionen solo desde la línea de comandos y que sean inaccesibles desde el navegador web con el método cli(). Cualquier ruta creada por cualquiera de los métodos de ruta basados ​​en verbos HTTP tampoco será accesible desde la CLI, pero las rutas creadas por el método add() seguirán estando disponibles desde la línea de comando:

<?php

$routes->cli('migrate', 'App\Database::migrate');

Opciones globales

Todos los métodos para crear una ruta (agregar, obtener, publicar, recurso , etc.) pueden tomar una serie de opciones que pueden modificar las rutas generadas o restringirlas aún más. La $options matriz es siempre el último parámetro:

<?php

$routes->add('from', 'to', $options);
$routes->get('from', 'to', $options);
$routes->post('from', 'to', $options);
$routes->put('from', 'to', $options);
$routes->head('from', 'to', $options);
$routes->options('from', 'to', $options);
$routes->delete('from', 'to', $options);
$routes->patch('from', 'to', $options);
$routes->match(['get', 'put'], 'from', 'to', $options);
$routes->resource('photos', $options);
$routes->map($array, $options);
$routes->group('name', $options, static function () {});

Aplicar filtros

Puede modificar el comportamiento de rutas específicas proporcionando filtros para que se ejecuten antes o después del controlador. Esto es especialmente útil durante la autenticación o el registro de API. El valor del filtro puede ser una cadena o una matriz de cadenas:

  • Haciendo coincidir los alias definidos en app/Config/Filters.php.
  • Filtrar nombres de clase.

Consulte Filtros del controlador para obtener más información sobre la configuración de filtros.

Filtro de alias

Especifica un alias definido en app/Config/Filters.php para el valor del filtro:

<?php

$routes->get('admin', ' AdminController::index', ['filter' => 'admin-auth']);

También puede proporcionar argumentos para pasar a los métodos before() y filtros de alias:after().

<?php

$routes->post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']);

Filtro de nombre de clase

Especifique un nombre de clase de filtro para el valor del filtro:

<?php

$routes->get('admin', ' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]);

Filtros Múltiples

Los filtros múltiples están deshabilitados de manera predeterminada. Porque rompe la compatibilidad con versiones anteriores. Si desea utilizarlo, debe configurarlo. Consulte Múltiples filtros para una ruta para obtener más detalles.

Usted especifica una matriz para el valor del filtro:

<?php

$routes->get('admin', ' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]);

Asignación de espacio de nombres

Si bien se agregará un espacio de nombres predeterminado a los controladores generados, también puede especificar un espacio de nombres diferente para usar en cualquier matriz de opciones, con la namespace opción. El valor debe ser el espacio de nombres que desea modificar:

<?php

// Routes to \Admin\Users::index()
$routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']);

El nuevo espacio de nombres solo se aplica durante esa llamada para cualquier método que cree una sola ruta, como get, post, etc. Para cualquier método que cree varias rutas, el nuevo espacio de nombres se adjunta a todas las rutas generadas por esa función o, en el caso de group(), todas las rutas generadas durante el cierre.

Limitar a nombre de host

Puede restringir grupos de rutas para que funcionen solo en ciertos dominios o subdominios de su aplicación pasando la opción “nombre de host” junto con el dominio deseado para permitirlo como parte de la matriz de opciones:

<?php

$routes->get('from', 'to', ['hostname' => 'accounts.example.com']);

Este ejemplo solo permitiría que los hosts especificados funcionen si el dominio coincide exactamente con accounts.example.com. No funcionaría en el sitio principal en example.com.

Limitar a subdominios

Cuando la subdomain opción está presente, el sistema restringirá las rutas para que solo estén disponibles en ese subdominio. La ruta solo coincidirá si el subdominio es el mismo a través del cual se está viendo la aplicación:

<?php

// Limit to media.example.com
$routes->get('from', 'to', ['subdomain' => 'media']);

Puede restringirlo a cualquier subdominio configurando el valor con un asterisco, ( *). Si está viendo desde una URL que no tiene ningún subdominio presente, esto no coincidirá:

<?php

// Limit to any sub-domain
$routes->get('from', 'to', ['subdomain' => '*']);

Compensación de los parámetros coincidentes

Puede compensar los parámetros coincidentes en su ruta por cualquier valor numérico con la offsetopción, siendo el valor el número de segmentos a compensar.

Esto puede ser beneficioso cuando se desarrollan API en las que el primer segmento de URI es el número de versión. También se puede usar cuando el primer parámetro es una cadena de idioma:

<?php

$routes->get('users/(:num)', 'users/show/$1', ['offset' => 1]);

// Creates:
$routes['users/(:num)'] = 'users/show/$2';

Prioridad de ruta

Las rutas se registran en la tabla de enrutamiento en el orden en que se definen. Esto significa que cuando se accede a una URI, se ejecutará la primera ruta coincidente.

https://aprendeinformaticas.com/
https://codeigniter.com/user_guide/incoming/routing.html