Symfony не работает роутинг

Маршрутизация¶

Когда ваше приложение получает запрос, оно вызывает действие контроллера 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 .

Совпадение HTTP-методов¶

По умолчанию, маршруты совпадают с любым глаголом HTTP ( GET , POST , PUT , и др.). Используйте опцию methods , чтобы ограничить глаголы, на которые долшжен реагировать каждый маршрут:

Читайте также:  Space engineers не работает планировщик

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/ ). Учитывая, что параметры маршрута принимают любые значения, нет возможности дифферинциировать эти два маршрута.

Если пользователь запрашивает /blog/my-first-post , оба маршрута совпадут, и Symfony будет использовать маршрут, который был определен первым. Чтобы исправить это, добавьте некоторую валидацию к параметру , используя опцию requirements :

Опция 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/ ).

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

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:

_controller Этот параметр используется для определения того, какой контроллер и действие выполняется при совпадении маршрута. _format Совпавшее значение используется для установки “request format” объекта Request . Это используется для таких вещей, как установка Content-Type ответа (например, формат json переводится в Content-Type для application/json ). _fragment Используется для установки идентификатора фрагмента, что является последней необязательной частью URL, которая начинается с символа # и используется для идентификации части документа. _locale Используется для установки локали в запросе.

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

Источник

Маршрутизация не работает в Symfony 3.4

Я создал новый проект Symfony 3.4, используя:

После этого я добавил следующие компоненты:

И создал контроллер:

Я добавил действие с маршрутом «легальный». Вот DefaultController:

Файл config / rout.yaml:

И конфиг / маршруты / аннотации.yaml:

Когда я захожу на домашнюю страницу, нет проблем, страница отображается. Но когда я пробую страницу / legal, у меня появляется 404:

Not Found — Запрошенный URL / Legal не найден на этом сервере.

php bin/console debug:router показывает ожидаемое:

Я очистил кеш с помощью команды console и удалив содержимое каталога var / cache. Но все равно 404.

Я новичок в 3.4. Любые идеи ? Спасибо.

4 ответа

Ну, как указал @Basel Issmail, Symfony / Flex не создает .htaccess , как это делал предыдущий установщик Symfony, и я забыл об этом.

У меня только что был минимальный файл конфигурации Apache:

Поэтому я создал файл .htaccess в /public/ (где находится файл index.php ), и минимально необходимая конфигурация выглядит примерно так:

Недостающая часть заключалась в том, чтобы переписать все запросы (кроме существующих файлов, таких как ресурсы) в index.php , чтобы Symfony обрабатывал маршрут.

— Изменить —

Вместо того, чтобы вручную создавать .htaccess, вы также можете просто использовать рецепт Symfony Flex:

Вы загрузили свое «Приложение» в Bundle в AppKernel.php? Существует массив, в котором вы должны открыть. Добавьте AppBundle.php вашего Bundle.

Это должно выглядеть вот так

Та же проблема с установкой Symfony на Synology DSM 6.2. Я подтверждаю, просто запустите «composer Требуется apache-pack», как указано в Scandel, и маршрутизация аннотаций будет работать отлично. Файл .htaccess с перезаписью cond будет автоматически создан в общей папке.

Вот файл .htaccess, созданный установкой symfony flex:

Похоже, вам нужно настроить RewriteBase с помощью apache , поскольку проблема не в /

Возможно, файл .htaccess даже отсутствует, поскольку вы используете Symfony / flex, и он по умолчанию не добавляет его, как в предыдущих выпусках Symfony.

Посетите эту страницу, чтобы настроить веб-сервер

.htaccess должен находиться в общей папке, и минимальная конфигурация для запуска приложения под Apache:

Источник

Оцените статью