Лонни Эцелл в очередной раз делится очень интересной информацией о новых возможностях. В этот раз речь пойдет о маршрутизации.

Основы маршрута

Чтобы освежить память вспомним, что в версии 3x маршрутизация была определена в простом массиве, где ключом был URl, а значением какой-либо элемент, куда необходимо было сделать направление.

Это был простой, элегантный и отлично работающий способ маршрутизации, что-то вроде этого:
 

$route['join']   = 'home/register';
$route['login']  = 'home/login';
$route['products/(:any)/details'] = 'products/show/$1';

Способности маршрутизации в других фреймворках превзошли эту простую элегантность. Даже в сообществе CodeIgniter, было несколько улучшенных маршрутизаторов способных послужить достойной альтернативой стандартному роутингу.

Итак, пришло время для обновления!

Первое, что необходимо было сделать — это возможность использования класса, вместо простого массива. Новые маршруты будут выглядеть следующим образом:
 

$routes->add('join',   'Home::register');
$routes->add('login',  'Home::login');
$routes->add('products/(:segment)', 'Products::show/$1');

Join маршрут направляется на главный контроллер, и его метод register(). Маршрут Products направляется на контроллер Products, с захваченным (:segment) передается на show () метод. 

Модуль типа Функциональность

Почему новый формат? Потому что никто не хочет быть ограниченным /application/Controllers каталогом. Теперь появится возможность проложить маршрут к любому классу/методу. 

Например, если у вас есть модуль Blog в пространстве имен App\Blog, то вы можете создать несколько маршрутов:

$routes->add('blog', 'App\Blog\Blog::index');
$routes->add('blog/category/(:segment)', 'App\Blog\Blog::byCategory/$1');

Если контроллер Blog живет в каталоге application/Controllers, отлично. Но если вы хотите переместить его в его собственную папку, скажем, application/Blog, вы можете обновить конфиг файл автозагрузки.

Замыкания

Маршруты больше не должны отображаться на контроллер. Если у вас есть простой процесс, вы можете указать путь к анонимной функции или замыканию, которое будет выполняться на месте любого контроллера.
 

$routes->add('pages/(:segment)', function($segment)
{
    if (file_exists(APPPATH.'views/'.$segment.'.php'))
    {
        echo view($segment);
    }
    else
    {
        throw new CodeIgniter\PageNotFoundException($segment);
    }
});

 

Заполнители

Все кто пользовался CodeIgniter привыкли к двум типам заполнителя:

:num будет соответствовать сегмент, содержащий только цифры.
:any будет соответствовать сегмент с любыми символами. 

Теперь в CodeIgniter 4 будут внедрены следующие заполнители:

  • (:any) будет соответствовать сегмент с любыми символами.
  • (:segment) будет соответствовать сегмент с любыми символами за исключением прямой черты (слэша /).
  • (:num) будет соответствовать сегмент, содержащий только цифры.
  • (:alpha) будет соответствовать сегмент, содержащий любой символ
  • (alphanum) будет соответствовать сегмент, содержащий комбинации из символов или чисел,

Также вы можете создать свой собственные правила маршрутизации, назначив регулярное выражение для него, поместив код в верхнюю часть файла маршрутизации.

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

HTTP Глаголы

Маршруты, добавленные таким образом будут доступны через HTTP-глаголы, чтобы проверить, является ли запрос GET, POST, PATCH, или даже из командной строки. 
 

$routes->get('products', 'Product::feature');
$routes->post('products', 'Product::feature');
$routes->put('products/(:num)', 'Product::feature');
$routes->delete('products/(:num)', 'Product::feature');
$routes->match(['get', 'post'], 'products/edit/(:num)', 'Product::edit/$1');
$routes->cli('maintenance/on', 'CLITools::maintenanceModeOn');

 

Создание стандартных ресурсов маршрутов

При работе с API лучше держать стандартный набор отображения маршрутов к тем же методам в каждом контроллере, просто чтобы сделать обслуживание проще. Вы можете легко сделать это с помощью метода ресурсов:

При работе с API-х лучше держать стандартный набор отображения маршрутов к тем же методам в каждом контроллере, просто чтобы сделать обслуживание проще. Вы можете легко сделать это с помощью метода ресурсов:

$routes->resources('photos');

Это создаст 5 стандартных маршрутов для ресурса:

HTTP Verb    Path                  Action    Used for...
GET             /photos                listAll     display a list of photos
GET             /photos/{id}          show      display a specific photo
POST           /photos               create     create a new photo
PUT             /photos/{id}          update    update an existing photo
DELETE       /photos/{id}          delete     deletes an existing photo

 

Нет больше магии

По умолчанию, URI, будет пытаться быть согласованным с контроллером / методом, если для него не существует маршрута. Это может быть легко обработано путем включения и выключения функции AutoRoute:
 

$routes->setAutoRoute(false);

Теперь, только маршруты, которые были определены, могут работать до приложения.
 

Группы

Маршруты могут быть сгруппированы вместе под общим префиксом. Это очень полезный функционал для организации маршрутизации.

Эти маршруты будут теперь все будут доступны под сегментом admin в URI, как:

example.com/admin/users
example.com/admin/blog

 

Окружения групп

Другая форма группировки, environment() — позволяет ограничить некоторые маршруты для работы только в конкретной среде. 
 

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

Перенаправление Старые маршруты

Если ваш сайт имеет несколько страниц, которые были перемещены, вы можете назначить перенаправление маршрутов, которые будут получать 302 (временный) статус и отправлять пользователя на нужную страницу.
 

$routes->addRedirect('users/about', 'users/profile');

Это позволит перенаправить любые маршруты, соответствующие users/about на новое место users/profile.
 

Использование маршрутов в представлениях

Одной из наиболее слабой вещью при создании ссылок внутри отображения, является изменение их адреса. Теперь CodeIgniter 4 предоставляет несколько различных инструментов, чтобы помочь обойти эту проблему.

Именованные маршруты

В любое время вы создать маршрут и можете назначить пользовательское имя на маршрут. Для возврата правильного относительного URL необходимо применять функцию route_to ():
 

// Create the route
$route->add('auth/login', 'Users::login', ['as' => 'login']);

// Use it in a view
<a href="<?= route_to('login') ?>">Login</a>

Именованные маршруты, используемые таким образом, могут также принимать параметры:
 

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

// Generate the relative URL to link to user ID 15, gallery 12
// Generates: /users/15/gallery/12
<a href="<?= route_to('user_gallery', 15, 12) ?>">View Gallery</a>

Обратная маршрутизация

Для еще более точного управления, вы можете использовать функцию route_to (), чтобы найти маршрут, который соответствует контроллеру / методу и параметрам.

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

// Generate the relative URL to link to user ID 15, gallery 12
// Generates: /users/15/gallery/12
<a href="<?= route_to('Galleries::showUserGallery', 15, 12) ?>">View Gallery</a>

 

Глобальные параметры

Любой из методов создания маршрута можно передать массив опций, которые могут помочь дополнительно уточнить маршрут, делая такие вещи, как:

  • назначить пространство имен для контроллеров
  • ограничить маршрут к определенному имени хоста, или суб-домену
  • сместить совпавшие параметры, чтобы игнорировать один или несколько (которые могли быть использованы для языка, версии, и т.д.)

 

Нужно больше? Настройте сами!

Если вы обнаружите, что вам нужно что-то отличное от стандартного маршрутизатора, то вы можете заменить класс RouteCollection вашим собственным и использовать свое решение. Класс RouteCollection отвечает только для чтения и разбора маршрутов, а не для выполнения фактической маршрутизации, так что все будет работать с вашим решением.
Более подробная информации появится с выходом официальной документации.

 

Ссылки по теме

Блог Лонни Эцелла: Routes in CodeIgniter 4
CodeIgniter Wikipedia: ru.wikipedia.org/wiki/CodeIgniter
Официальный сайт CodeIgniter: www.codeigniter.com
Официальный форум CodeIgniter: forum.codeigniter.com