Как сделать роутинг php

Добавил пользователь Валентин П.
Обновлено: 04.10.2024

Итак, чем же мы займемся? Мы напишем роутинг в стиле скелетона.

Что же такое роутинг и с чем его едят:

А если проще и ближе к делу - роутинг, это средство определения и контроля маршрута запроса пользователя. В PHP это чаще всего замена жесткого пути к файлам на диске, на программную обработку запроса и замену файлов на методы

Для готовки маршрутизатора нам понадобятся следующие ингредиенты:

1. Прямые руки (2шт.)(при кривизне выпрямить в заборе).
2. Более менее внятный блокнот. Советую Notepad++
3. Настроенный локальный сервер/хостинг
4. Терпение.
5. Собсно программист или что-то на него похожее

Файл .htaccess должен лежать в корневой папке сайта, тут же необходимо создать скрипт index.php, который является точкой входа. Давайте запишем в index.php одну строку, для проверки работы перенаправления:

Для того, чтобы константы и другие данные конфига мы могли использовать во всем проекте, в файле index.php необходимо подключить скрипт config.php.
Помимо подключения файла с настройками, в index.php нужно создать подключение к базе данных, подключить скрипт с ядром сайта и запустить роутер, в котором будет происходить маршрутизация.
Теперь по порядку, создание соединения с базой данных будет находиться в index.php для того, чтобы соединение открывалось только один раз. Единожды открыв соединение, мы сможем использовать его во всех контроллерах и моделях, но об этом чуть позже. Сейчас просто создадим соединение с базой. Для работы с бд я решил использовать PDO. Подробнее почитать про PDO можно тут .
Ядро сайта расположим в папке core и назовем скрипт core.php, тут мы напишем функцию, которая будет сама подключать, необходимы для работы классы. Такая функция очень облегчит и упростит нам работу с контролерами, моделями и тд. Поскольку, забегая вперед скажу, что каждый контролер и каждая модель будут представлять собой отдельный класс.
Помимо авто подключения классов, добавим в ядро создания хранилища (реестра), в котором будем хранить все необходимые объекты и переменные, которые могут пригодиться в любом месте проекта.
Роутер тоже подключим в индексном файле, он будет анализировать URL и подключать необходимый контроллер и экшен. Что такое контролер я писал в предыдущей статье, а информацию про экшен я пропустил умышленно, не став нагружать лишней информацией. Так что же такое экшен?
Контролер это класс, в котором заключены различные методы, при MVC подходе каждый метод будет являться экшеном. То есть экшен(action) – это метод класса, который будет обрабатывать данные и передавать их в представление (в шаблон). Может быть, пока не совсем понятно, но после примера все станет на свои места.
На данном этапе теории достаточно, давайте перейдем к практике. Приведу код файлов, работу которых, я описывал выше.
Код скрипта index.php:

Класс хранилища Registry.php, будет находиться в папке /classes/

Код файла router.php, который находиться в папке /classes/

Теперь необходимо создать папки для хранения контроллеров, шаблонов и моделей – в корне создадим три папки controllers, views и models. И создадим несколько тестовых файлов /controllers/index.php, /views/index/index.php и /models/model_users.php, а теперь заполним файлы:
Для контроллера:

Как вы могли заметить, класс контролера наследуется от родительского класса Controller_Base. Это сделано, для того, чтобы упростить класс контролера. Поскольку нам еще необходимо подключать класс для работы с шаблонами, его подключение вынесено в Controller_Base.
Приведу его код, он расположен в папке /classes/ и называется controller_base.php :

Теперь осталось только разобраться с шаблонами. В абстрактном классе Controller_Base мы вызываем класс Template и передаем ему имя шаблона и имя контроллера.
Код класса Template, который лежит тут /classes/ и называется template.php

Если вы внимательно прочитали код, то наверняка поняли, что для отображения на страницах у нас используется шаблон first_layouts и вьюха(отображение) index.php – ее код я приводил чуть выше. Все что нам осталось, это создать файл шаблона first_layouts. Расположим его в папке /views/layouts/first_layouts.php
Шаблон будет содержать вот такой код:

Запос пользователя в адресной строке поступает в Front Controller где он обрабатывается с помощью роутера (маршрутизатора) в соответсвии с нашими маршрутами (роутами) прописанными в отдельном файле. Здесь же определяется какой контроллер и какой его метод (экшен) будет обрабатывать данный запрос. Уже назначенный контролер будет взаимодействовать с БД (базой данных) для получения необходимой информации и вызывать соответствующий файл представления (вид) для передачи пользователю запрашиваемой информации.

Для того, чтобы понять как это работает, лучше всего представить все в виде такой схемы:


Создаем файловую структуру сайта:

Папки:

  1. controller
  2. config
  3. components
  4. model
  5. views

Файлы:


Сразу приведу файл .htaccess полностью. Его нужно создать раньше, если вы работаете на OpenServer

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

Для подключения мы используем полный путь на диске, который мы получаем с помощью функции dirname() и псевдо константы __FILE__ .

Для проверки содержимого константы ROOT (полный путь от корня файловой системы), мы можем вывести переменную ROOT следующим образом:

Сразу после строк создания константы ROOT и подключения файла Router.php -

Соединения с БД на этом этапе мы выполнять не будем и вернемся к нему позже.

Вызов роутера можно добавить сейчас или сразу после описания нашего ротера я следующем шаге. Он будет заключаться в создании экземпляра класса Роутер - $router = new Router() и запуске метода run() - $router->run(); ;

Коль скоро мы подключили файл Router.php , то нам остается его создать в папке components

B нем пропишем следующий строки :

Теперь, если мы откроем наш сайт, то увидим строки - It is file Roter.php -. Это говорит о том. что все подключено и правильно работает

Таким образом мы запустили наш Router и передали ему управление

Router

Первое с чего нам следует начать - маршруты (роуты). Они будут храниться в отдельном файле. Это очень удобно.

В папке config создадим для этого файл routes.php

Здесь мы и разместим наши роуты в виде массива:

routes.php

Роуты представляют собой пару в массиве.Запрос (то что пользователь набирает в адресной строке браузера) - Например: 'news' и строка - 'news/index' , которая содержит имя контроллера news (первая часть), и имя экшена index (функции обработчика запроса) - вторая часть.

Этот код - 'news' => 'news/index' показывает, что будет вызван метод - actionIndex в контроллере - NewsController

Здесь мы сами решаем, какой метод и какой контроллер будет обрабатывать наш запрос. Делаем это мы на этапе разработки нашего сайта.

Теперь наша задача заставить наш Router прочитать маршруты и помнить их на время выполнения кода.

Специально для этого мы создали переменную private $routes; и конструктор public function __construct() , в котором мы прочитаем и запомним роуты.

В конструкторе пишем две строки:

В первой - $routesPath = ROOT.'/config/routes.php'; мы указываем путь к роутам. Она состоит из пути к базовой директории ROOT и пути к созданному файлу.

Во второй строке мы присваиваем свойству routes - $this->routes массив, который хранится в файле routes.php

Теперь в наше свойство попадет нужный нам массив.

Для того чтобы проверить все ли у нас подключилось и правильно работает мы в методе run() сделаем распечатку массива : print_r($this->routes);

Все конечные версии вы можете посмотреть на Гугл Диске


Файл Router.php на данный момент полностью: ЗАДАЧА 3

Теперь нам нужно реализовать метод run(). Это та часть, которая отвечает за анализ запроса и передачу управления

  1. Получение запроса
  2. Проверить наличие такого запроса в файле routes.php
  3. Если найдется совпадение. то определить какой контроллер и экшен будут обрабатывать это запрос
  4. Подключить файл, который содержит класс-контроллер
  5. Создать объект этого класса контроллер и вызвать нужный метод

Теперь по порядку:

Получение запроса

Файл Router.php на данный момент полностью:

Здесь мы из супер глобального массива $_SERVER по ключу 'REQUEST_URI' получаем нужную строке запроса

Теперь идем на наш сайт и в строке запроса дописываем /news/ - например. Или любое другое значение. Нажимаем Enter и видим значение из строки на нашем сайте.


Теперь, для того, чтобы сделать наш код понятнее и красивее, мы можем вынести этот код в отдельный метод - private function getURI() ,а вызов сделаем из функции run() таким образом - $uri = $this->getURI();

Файл Router.php на данный момент полностью:

Метод getURI() мы сделали приватным, тем самым применили инкапсуляцию, потому как обращаться к этому методу мы планируем только из класса Роутер

Еще раз проверяем. Должно все работать точно так же как и в прошлый раз.

Проверить наличие такого запроса в файле routes.php

Теперь нам нужно найти такую строку запроса, которая содержится в переменной - $uri в наших маршрутах в файле -routes.php

Файл Router.php на данный момент полностью:

Файл Router.php на данный момент полностью:

Здесь для каждого маршрута $this->routes , который находится в нашем массиве,мы помещаем в переменную - $uriPattern строку запросов из роутов файла- routes.php (левая часть до => знака), а в переменную $path - путь обработчика

Перезагружаем страницу и видим:


Теперь мы будем сравнивать строку запроса $uri с данными которые содержатся в роутах- $uriPattern

Это легко сделать используя функцию preg_match() Для этого мы передаем в нее строку запроса - $uri и данные из наших роутов - $uriPattern

Для проверки выводим +. То есть если наш запрос в адресной строке будет совпадать с роутами то увидим на странице +.

Сохранили изменения в файле. Заходим на сайт, перезагружаем и получаем:


Причем, если теперь вы введете в строку запроса значение несоответствующее нашим роутам (' news ' => 'news/index',' products ' => 'product/list' ), то ничего не увидите на сайте.

То есть, пока что наш роутер готов обработать два запроса - news и products по определенному правилу.

Обратите внимание, что в качестве разделителей в патерне "~$uriPattern~" я использовал тильду, так как в нашем патерне могут содержаться слэши- '/' например при таком адресе страницы (' news/archive' => 'news/archive'). Файл Router.php на данный момент полностью:

Итак, если условие соблюдается. то в переменной $path будут находиться имя контроллера и экшена. Чтобы в этом убедиться вам нужно заменить + в выводе echo на переменную $path - вот так: echo $path;

Идем на страницу сайта, вводим запрос (существующий) и получаем:


Определяем какой контроллер и экшен обрабатывают запрос

Мы можем это получить с помощью функции - explode(), чтобы разделить строку на две части

Результат вы можете увидеть на скриншоте, а код файла Router.php ниже


Файл Router.php на данный момент полностью: '; > > > >

В результате мы получили два элемента, первый относящийся к контроллеру и второй к экшену

Теперь мы можем получить имя контроллера:

Здесь мы используем функцию array_shift() , она получает первый элемент из массива $segments и удаляет его. К этому значению мы добавляем слово 'Controller', поскольку мы приняли за систему такое именование конроллеров.

теперь нам остается сделать заглавной первую букву в названии контроллера функцией :


$controllerName = ucfirst($controllerName);
И теперь можно сохранить и проверить наш сайт.


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


Файл Router.php на данный момент полностью:

Да, кстати, теперь самое время добавить в папку controllers новые файлы ArticleController.php , NewsController.php и ProductController.php

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

Вначале нам нужно создать наши контроллеры.

И вот теперь самое время добавить в папку controllers новые файлы ArticleController.php , NewsController.php и ProductController.php

Содержимое файлов NewsController.php и ProductController.php и ArticleController.php это соответствующий класс и один метод, который пустой и просто возвращает - true

Продолжаем работать над файлом Router.php и далее нам нужно подключить файл класса контроллера. Так как мы уже знаем его имя - $controllerName и используем определенный подход к названию фалов в папке контролеров, то сделать это очень просто вот таким кодом:

В этой части кода $controllerFile = ROOT . '/controllers/' .$controllerName. '.php'; мы определяем файл который необходимо подключить. Для этого мы прописываем путь к нему используя имя класса

Далее мы непосредственно подключаем его, предварительно проверяя существует ли он?

Все необходимые действия в виде анализа запроса и подключения нужного файла мы выполнили

Создаем объект класса контрллера - $controllerObject = new $controllerName;. Вместо имени класса мы подставляем переменную, которая содержит строку с именем этого класса.

Далее для этого объекта $controllerObject мы вызываем метод $actionName(), точно так же мы используем переменную, которая содержит строку с названием нужного метода. В наших методах в файлах контолерах, мы писали return true для того, чтобы мы могли передать это значение определенной переменной - $result. В рузельтате, если метод сработал, то мы сможем об этом узнать и оборвать весь цикл - if ($result != null) < break; >. , который ищет совпадения в наших маршрутах.

Теперь наша система практически готова. Осталось добавить несколько штрихов в наши методы контроллеров и проверим ее на работоспособность. Например в NewsController.php (перед return true) - echo "NewsController.php actionIndex ";


Это позволило нам убедиться, что зaпущенн нужный нам метод. Точно тоже мы проделаем и с другим контроллером

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

Все файлы проекта можно посмотреть на Гугл Диске

Далее Модель, Представление и усовершенствования класса Роутер


1 комментарий:

VarangaOfficial - варанга от грибка цена - исключительно достоверные, проверенные факты. Воспользовавшись данным ресурсом, вы получите возможность узнать полную информацию касательно данного лекарственного средства. Лично увидеть данные о проведенных клинических исследований, прочитать отзывы реальных покупателей и врачей. Ознакомиться с инструкцией по применению, прочитать об особенностях и методах работы комплекса, уяснить, в чем заключаются особенности работы крема Варанга, где можно купить оригинальный препарат и, как избежать покупки подделки. Мы очень тщательно и скурпулезно проверяем размещаемые на сайте данные. Предоставляем посетителям нашего онлайн-ресурса сведения, которые были взяты исключительно из надежных источников. Если вы обнаружили у себя признаки грибкового поражения стоп или же долго и безрезультатно пытаетесь избавиться от этого неприятного недуга, наш сайт покажет вам быстрый и простой способ решения проблемы. Присоединяетесь и живите полноценной, здоровой жизнью. Теперь все ответы на самые популярные и волнующие пользователей вопросы, собраны на одном ресурсе.

В предыдущих постах мы разработали минимальную структуру фреймворка. В этой статье, наведем немного лоска - добавим простенькую тему с bootstrap'ом, меню и подробнее рассмотрим работу шаблонизатора и роутера (маршрутизатора сайта).

Роутер

В прошлой статье мы создали роутер, который используя логику регулярных выражений распознает входящую sef ссылку и направляет на нужный контроллер и его метод.

Т.е. из такой строки

роутер делает массив

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

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

Кроме того вы можете видеть, что мы изменили правую часть массива.

Внесем изменения в код роутера, а потом разберем его работу.

Во первых мы заполняем массив выходных данных значениями по умолчантю, которые берем из нашего config.php. Затем мы парсим входной $path на наличие get переменных. Если они есть, то их просто нужно добавить к массиву выходных данных. parse_url - разделяет url на составляющие. Одной из таких составляющих является query. Это все что в URL идет после знака вопроса

Эту строку key=value параметров в свою очередь парсит функция parse_str

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

На 12 строчке мы видим перебор всех правил из конфига. На 13 проверяем - подходит ли очередное правило. Если да, то берем массив результатов и поочередно заменяем его элементами - правую часть правила.

Сработало правило '([a-z0-9+_\-]+)/([a-z0-9+_\-]+)/(5+)' => '$controller/$action/$id',

Тогда массивом результатов применения его левой части к входной строке /user/profile/15 будет массив

Перебирая этот массив, начиная со второго элемента, заменяем в правой части правила $controller/$action/$id ключи $([a-z]+)

Т.е. на строке 14, при каждой замене, правая часть правила будет менятся так

На первый взгляд - это бессмысленные действия. Какую строку пустили на вход /user/profile/15 такую и получили на выходе правила

Но это только на первый взгляд. На выходе мы получили стандартизованный URI, применив к которому операцию explode, получим в первом элементе название контроллера, во втором - метода, в тертьем - id

Для большей ясности, добавим в конец массива правил в config.php, правило

В результате работы этого правила, наш роутер любуй запрос html страницы (к примеру /about.html без указания контроллера и метода), направит в контроллер page и метод read, а в параметр id пойдет строка about

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

Шаблонизатор

Чтобы начать делать шаблон для нашего фреймворка, нам потрбуется какая-нибудь сверстанная html страничка. К примеру возьмем бесплатную тему с сайта бутсрапа

Жмите ctrl+u в своем браузере и просто копируйте весь исходный код в файл viws/main.php - это и есть шаблон. Но его еще нужно доработать. Удалим все подключения стилей и скриптов через html разметку. Мы будем подключать необходимые скрипты через php. Это дает определенную уверенность, что в любом шаблоне всегда будет присутствовать набор файлов вашего фреймворка, независимо от того, использовал ли их верстальщик при верстке.

Для стилей и скриптов в корне проекта создадим отдельную папку. Обычно ее называют assets , а в ней подпапки - css - для стилей, js - для скриптов, и images - для изображений. При этом последнюю папку нужно использовать только для тех изображений, которые учавствуют в дизайне сайта, а не в его наполнении. Для наполнения лучше выделить отдельную директорию - media/images в корне сайта.

Скачем свежий бутстрап и последнюю версию jquery. Кладем их в папку assets/js/libs/ . Остальные стили темы вам придется скачать самостоятельно.

Все стили и скрипты лежат по своим папкам, но как же их подключить. В нашем шаблонизаторе нет таких методов. Их необходимо написать. Добавлять их мы будем в файл ideal/classes/controller.php . Добавим следующие методы

  • private function addAsset($link, $where = 'head', $asset = 'script', $type = 'url')
  • public function addScript($link, $where = 'head')
  • public function addStyleSheet($link, $where = 'head')
  • public function addScriptDeclaration($link, $where = 'head')
  • public function addStyleSheetDeclaration($link, $where = 'head')

Писать код нам придется для метода addAsset, все остальные методы - это вызов addAsset с различными параметрами, и сделаны скорее для удобства.

Добавим в класс следующее поле

В нем будут храниться данные о всех подключаемых стилях и скриптах. Далее код addAsset

$hash - вычисляется лишь для того, чтобы не подключать к странице одни и те же скрипты дважды. $where - это место, куда мы подключаем скрипты. Перед или перед

Когда ваше приложение получает запрос, оно вызывает действие контроллера action , чтобы сгенерировать ответ. Конфигурациия маршутизации определяет, какое действие выполнять для каждого входящего URL. Она также предоставляет другие полезные функции, вроде генерирования дружелюбных для SEO URL (например, /read/intro-to-symfony вместо index.php?article_id=57 ).

Создание маршрутов¶

Маршруты могут быть сконфигурированы на YAML, XML, PHP или с использованием атрибутов или аннотаций. Все форматы предоставляют одинаковые функции и производительность, поэтому выбирайте то, что вам больше нравится. Symfony рекомендует атрибуты , так как это удобно - помещать маршрут и контроллер в одно место.

Создание маршрутов в виде атрибутов или аннотаций¶

В PHP 8, вы можете использовать нативные атрибуты для немедленной конфигурации маршрутов. В PHP 7, где атрибуты недоступны, вы можете использовать вместо этого аннотации, предоставленные библиотекой Аннотаций Doctrine.

В случае, если вы хотите использовать аннотации вместо атрибутов, единожды выполните эту команду в вашем приложении, чтобы их включить:

New in version 5.2: Возможность использовать PHP-атрибуты для конфигурации маршрутов, была представлена в Symfony 5.2. Раньше, Аннотации Doctrine были единственным способом аннотировать действия контроллера конфигурацией маршрутизации.

Эта команда также создает следующий файл конфигурации:

Эта конфигурация сообщает Symfony, что нужно искать маршруты, определенные как аннотации в любом PHP-классе, хранящемся в каталоге src/Controller/ .

Представьте, что вы хотите определить маршрут для URL /blog в вашем приложении. Чтобы сделать это, создайте класс контроллера как показано ниже:

Эта конфигурация определяет маршрут под названием blog_list , который совпадает, когда пользователь запрашивает URL /blog . Когда происходит совпадение, приложение выполняет метод list() класса BlogController .

Строка запроса URL не рассматривается при сопоставлении маршрутов. В этом примере, URL вроде /blog?foo=bar и /blog?foo=bar&bar=foo будут так же совпадать с маршрутом blog_list .

Если вы определяете несколько PHP-классов в одном файле, Symfony загружает только маршруты первого класса, игнорируя все другие.

Имя маршрута ( blog_list ) сейчас не важно, но будет иметь значение позже, когда вы будете генерировать URL . Вам нужно только иметь в виду, что каждое имя маршрута должно быть уникальным в приложении.

Создание маршрутов в файлах YAML, XML или PHP¶

Вместо определения маршрутов в классах контроллера, вы можете определять их в отдельном файле YAML, XML или PHP. Главное преимущество - они не будут требовать никаких дополнительных зависимостей. Главный недостаток - вам нужно работать с несколькими файлами при проверке маршрутизации какого-то действия контроллера.

Следующий пример показывает, как определять в YAML/XML/PHP маршрут под названием blog_list , который ассоциирует URL /blog с действием list() BlogController :

New in version 5.1: Начиная с Symfony 5.1, по умолчанию Symfony загружает только маршруты, определенные в формате YAML. Если вы определяете маршруты в формате XML и/или PHP, обновите файл src/Kernel.php , чтобы добавить поддержку расширений файлов .xml и .php .

HTML-формы поддерживают только методы GET и POST . Если вы вызываете маршрут с другим методом из HTML-формы, добавьте скрытое поле под названием _method с методом для использования (например, type="hidden" name="_method" value="PUT"/> ). Если вы создаете ваши формы с помощью Форм Symfony это делается за вас автоматически.

Совпадающие выражения¶

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

Значение опции condition - это любое валдиное выражение ExpressionLanguage и может использовать любую из этих переменных, созданных Symfony:

context Экземпляр RequestContext , который содержит наиболее фунламентальную информацию о сопоставляемом маршруте. request Объект Запроса Symfony , который представляет текущий запрос.

За кулисами. выражения компилируются в чистый PHP. Из-за этого, использование ключа condition не вызывает дополнительной нагрузки кроме времени, необходимого для выполнения низлежащего PHP.

Условия не берутся во внимание при генерировании URL (что объясняется позже в этой статье).

Отладка маршрутов¶

По мере роста вашего приложения, у вас в итоге будет много маршрутов. Symfony включает в себя несколько команд, чтобы помочь вам с отладкой проблем маршрутизации. Для начала, команда debug:router перечисляет все маршруты вашего приложения в том же порядке, в котором их оценивает Symfony:

Передайте имя (или его часть) какого-то маршрута этому аргументу, чтобы отобразить детали маршрута:

Другая команда называется router:match и она показывает, какой маршрут будет совпадать с заданным URL. It’s useful to find out why some URL is not executing the controller action that you expect:

Параметры маршрута¶

Предыдущие примеры определяют маршруты, где URL никогда не изменяется (например, /blog ). Однако, часто определяют маршруты, где какая-то часть - переменная. Например, URL для отображения какого-то поста блога скорее всего будет включать в себя название или слаг (например, /blog/my-first-post или /blog/all-about-symfony ).

В маршрутах Symfony, переменные части заключены в < . >и должны иметь уникальное имя. Например, маршрут для отображения содержания поста блога, определяется как /blog/ :

Имя переменной части ( в этом примере) используется для создания PHP-переменной, где хранится содержание этого маршрута и передается контроллеру. Если пользователь посещает URL /blog/my-first-post , Symfony выполняет метод show() в классе BlogController , и передает аргумент $slug = 'my-first-post' методу show() .

Маршруты могут определять любое количество параметров, но каждый из них может быть использовать только единожды в каждом маршруте (например, /blog/posts-about-/page/ ).

Валидация параметров¶

Представьте, что ваше приложение имеет маршрут blog_show (URL: /blog/ ) и маршрут blog_list (URL: /blog/ ). Учитывая, что параметры маршрута принимают любые значения, нет возможности дифферинциировать эти два маршрута.

Опция requirements определяет `регулярные PHP-выражения`_ , которым должны соответствовать параметры маршрута для того, чтобы совпадал весь маршрут. В этом примере, \d+ - это регулярное выражение, которое совпадает с однозначным числом любой длины. Теперь:

URL Маршрут Параметры
/blog/2 blog_list $page = 2
/blog/my-first-post blog_show $slug = my-first-post

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

Параметры также поддерживают свойства PCRE Unicode, которые являются последовательностями экранирования, совпадаюшими с общими типами символов. Например, \p совпадает с любым заглавным символом на любом языке, \p совпадает с любым греческим символом и т.д.

При использовании регулярных выражений в параметрах маршрута, вы можете установить опцию маршрута utf8 как true , чтобы сделать так, чтобы любой символ . совпадал с любым символом UTF-8, а не только с одним битом.

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

Необязательные параметры¶

В предыдущем примере, URL blog_list - /blog/ . Если пользователи посещают /blog/1 , он будет совпадать. Но если они посетят /blog , он не будет совпадать. Как только вы добавите к маршруту параметр, он должен иметь значение.

Вы также можете сделать так, чтобы blog_list снова совпадал, когда пользователь посещает /blog , добавив значение по умолчанию к параметру . При использовании аннотаций, значения по умолчанию определяются в аргумнтах действия контроллера. В других форматах конфигурации они определяются опцией defaults :

Теперь, когда пользователь посещает /blog , маршрут blog_list будет совпадать, а $page по умолчанию будет иметь значение 1 .

Вы можете иметь более одного необязательного параметра (например, /blog// ), но все после необязательного параметра должно быть необязательно. Например, //blog - это валидный путь, но page всегда будет обязательным (т.е. /blog не будет совпадать с этим маршрутом).

Если вы хотите всегд включать какое-то значение по умолчанию в сгенерированном URL (например, для генерирования /blog/1 вместо /blog в предыдущем примере), добавьте символ ! перед именем параметра: /blog/

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

Чтобы дать значение по умолчанию null любому параметру, ничего не добавляйте после символа ? (например, /blog/ ). Если вы так сделаете, не забудьте обновить типы связанных аргументов контроллера, чтобы позволить передачу значений null (например, замените int $page на ?int $page )

Параметр приоритетности¶

New in version 5.1: Параметр priority был представлен в Symfony 5.1

Symfony оценивает маршруты в порядке, котором они определены. Если путь маршрута совпадает со многими разными паттернами, он может предотвратить другие маршруты от совпадения. В YAML и XML вы можете перемещать определения маршрутов вверх и вниз в файле конфигурации, чтобы контролировать их приоритетность. В маршрутах, определенных как PHP-аннотации или атрибуты, это намного сложнее сделать, поэтому вы можете установить необязательный параметр priority в таких маршрутах, чтобы контролировать их приоритетность:

Параметр приоритета ожидает целое значение. Маршруты с более высоким приоритетом сортируются до маршрутов с более низким приоритетом. Значение по умолчанию, если параметр не определен, - 0 .

Конверсия параметров¶

Распространенной потребностью маршрутизации является конверсия значения, хранящегося в некотором параметре (например, целое число, действующее, как ID пользователя), в другое значение (например, объект, представляющий пользователя). Эта функция называется “param converter”.

Чтобы добавить поддержку “param converters”, нам нужен SensioFrameworkExtraBundle:

Теперь, оставьте предыдущую конфигурацию маршрута, но измените аргументы действия контроллера. Вместо string $slug , добавьте BlogPost $post :

Если ваши аргументы контроллера включают в себя подсказки для объектов ( BlogPost в этом случае), “param converter” делает запрос в базу данных, чтобы найти объект, использующий параметры запроса ( slug в этом случае). Если объект не найден, Symfony автоматически генерирует ответ 404.

Прочтите `полную документацию param converter`_ , чтобы узнать о преобразователях, предоставленных Symfony, и о том, как их сконфигурировать.

Специальные параметры¶

В дополнение к вашим собственным параметрам, маршруты могут иметь любые следующие параметры, созданные Symfony:

Вы можете добавить эти атрибуты (кроме _fragment ) как в индивидуальных маршрутах, так и в импортированных. Symfony определяет некоторые особые атрибуты с одинаковым именем (кроме нижнего подчеркивания в начале), поэтому вам может быть легче их определить:

Читайте также: