- Symfony4 Аннотация маршрутизации не работает
- 8 ответов
- Механизм аннотаций в Symfony — как все это работает?
- Решение
- Шаг 5: Поиск и устранение неисправностей
- Установка дополнительных зависимостей¶
- Понимание окружений Symfony¶
- Управление конфигурациями окружений¶
- Логирование всех действий¶
- Изучение средств отладки Symfony¶
- Настройка среды разработки¶
- Отладка в продакшене¶
- Маршрутизация¶
- Создание маршрутов¶
- Создание маршрутов в виде атрибутов или аннотаций¶
- Создание маршрутов в файлах YAML, XML или PHP¶
- Совпадение HTTP-методов¶
- Совпадающие выражения¶
- Отладка маршрутов¶
- Параметры маршрута¶
- Валидация параметров¶
- Необязательные параметры¶
- Параметр приоритетности¶
- Конверсия параметров¶
- Специальные параметры¶
Symfony4 Аннотация маршрутизации не работает
Я только начал изучать Symfony. Я в точности следую этому официальному учебнику. Маршрутизация работает хорошо, когда выполняется с config/routes.yaml , но при использовании аннотаций :
Я получаю эту ошибку:
8 ответов
Я узнал свою ошибку. Я использовал неправильное пространство имен для маршрутизации.
Это должно было быть:
EDIT : Я хотел удалить этот вопрос, но система не позволила мне.
Убедитесь, что вы установили annotations библиотеку с composer require annotations Это была моя проблема, а не другие, описанные здесь.
Убедитесь, что вы импортировали необходимые классы в свой контроллер.
Я хочу дать дополнительный совет об ошибках аннотации в symfony4:
Я решил свою проблему с этим:
Мой проект не имеет config / routs / annotation.yaml, поэтому создайте этот файл и напишите следующие строки:
У меня была такая же проблема с моим первым проектом Symfony 4 на стандартном веб-сервере apache.
Создание файла .htaccess в моей общей папке устранило проблему.
В моем случае добавление «apache bundle» решило проблему:
Это необходимо, если вы запускаете symfony в браузере через / public /.
У меня была та же проблема (в моем проекте Symfony5), но моей ошибкой было использование одинарных кавычек вместо двойных кавычек для маршрута и имени маршрута. Иногда маленькие глупые ошибки будут тратить много вашего времени. Кстати, в SF4 / SF5 мы должны избегать использования Routing of FrameworkExtraBundle.
Мы должны использовать компонент Symfony (Routing / Annotation).
Symfony 4 с файлом .htaccess в общей папке решает проблему с помощью аннотации маршрутизации.
Источник
Механизм аннотаций в Symfony — как все это работает?
Я начал изучать Symfony (4.1) и у меня есть вопрос об аннотациях.
Насколько я знаю, аннотации — это просто комментарии с точки зрения php, и они не являются частью самого языка. Однако в Symfony они довольно мощная вещь.
Я хочу знать, как все это работает.
- Есть ли препроцессор кода, который динамически анализирует исходные файлы и создает новые объекты php?
- Но если это так, как это влияет на производительность приложения?
- Почему я должен использовать специальные пространства имен для определенных аннотаций?
Проще говоря, я хотел бы знать, как работают аннотации в Symfony, механизм этой функции.
Решение
Да, действительно, аннотации не являются частью самого языка. Но они также не являются частью платформы Symfony.
Аннотации обычно обрабатываются doctrine/annotations пакет (наиболее распространенный). Он использует отражение, чтобы прочитать и проанализировать эти комментарии и преобразовать их в объекты аннотаций (каждая аннотация имеет класс аннотации который он представляет).
Затем дело до библиотеки, чтобы использовать сгенерированные объекты, представляющие эти аннотации.
Итак, чтобы ответить на первый вопрос — да, есть препроцессор. Но он не «создает новые сущности php», потому что это работа для библиотеки, которая использует эти аннотации (например, платформа Symfony или Doctrine ORM).
То, как это влияет на производительность, зависит от библиотеки, которая их использует. Если они будут анализироваться при каждом запросе, это действительно повлияет на производительность. Так, например Symfony и Doctrine ORM кэшируют эти данные или создают прокси-классы и т. Д.
Таким образом, ответ на второй вопрос — возможно, если он используется неправильно, но обычно это не так (в производственной среде), поскольку они просто не анализируются каждый раз.
Последний вопрос на самом деле не относится к аннотациям. Поскольку аннотации на самом деле являются классами, причина их использования в именах также одинакова. Чтобы избежать конфликтов между библиотеками и ради удобочитаемости.
Источник
Шаг 5: Поиск и устранение неисправностей
Настройка проекта также подразумевает наличие правильных инструментов для отладки.
Установка дополнительных зависимостей¶
Помните, наш проект создан с очень небольшим количеством зависимостей: без шаблонизатора, без инструментов для отладки, без логера. Такой подход позволяет добавить другие зависимости только тогда, когда они вам нужны. Зачем вам шаблонизатор, если вы разрабатываете HTTP API или CLI-инструмент?
Как добавить больше зависимостей? Через Composer. Помимо «обычных» Composer-пакетов, мы будем работать с двумя «специальными» видами пакетов:
- Компоненты Symfony: пакеты с базовой функциональностью и низкоуровневыми абстракциями, необходимые большинству приложений (маршрутизация, консоль, HTTP-клиент, почтовый клиент, кеш и т.д.);
- Бандлы Symfony: пакеты, которые добавляют высокоуровневую функциональность или предлагают интеграцию со сторонними библиотеками (эти бандлы в основном разрабатываются сообществом).
Для начала давайте добавим Symfony Profiler, который поможет сэкономить много времени в поиске источника проблемы:
profiler — это псевдоним для пакета symfony/profiler-pack .
Псевдонимы — это не функция самого Composer, а концепция Symfony, чтобы облегчить нам жизнь. Псевдонимы — это ярлыки для популярных Composer-пакетов. Вашему приложению нужен ORM? Установите orm . Хотите разработать API? Установите api . Псевдонимы автоматически преобразуются в один или несколько обычных Composer-пакетов. Псевдонимы назначаются основной командой Symfony.
Ещё одна интересная особенность — можно не указывать вендора symfony в имени пакета. Поэтому, например, вместо symfony/cache набирайте cache .
Мы уже упоминали Composer-плагин symfony/flex . Псевдонимы — лишь одна из его функциональных возможностей.
Понимание окружений Symfony¶
Вы заметили флаг —dev при использовании команды composer req ? Поскольку Symfony Profiler имеет смысл использовать во время разработки, то не стоит устанавливать его в продакшене.
Symfony поддерживает создание окружений. По умолчанию есть три окружения с возможностью добавить дополнительные: dev , prod и test . Все окружения используют один и тот же код, но имеют разные конфигурации.
Например, в окружении dev все инструменты отладки включены. Когда как в окружении prod такого нет, потому что приложение должно быть оптимизировано для повышения производительности.
Изменяя значение переменной окружения APP_ENV можно переключаться с одного окружения на другое.
Во время развёртывания на SymfonyCloud, окружение (сохранённое в APP_ENV ) автоматически переключится на prod .
Управление конфигурациями окружений¶
Переменная APP_ENV может быть задана с помощью «настоящих» переменных окружения в терминале:
Переменные окружения, такие как APP_ENV , рекомендуется явно определять на продакшен-серверах. Однако в процессе разработки установка таким образом множество переменных окружения может стать утомительной. Поэтому вместо этого определите их в файле .env .
При создании проекта был автоматически сгенерирован файл .env :
Благодаря использованию рецептов Symfony Flex, любой пакет может добавить свои переменные окружения в этот файл.
Файл .env хранится в репозитории и содержит значения по умолчанию для продакшена. Вы можете задать свои значения, создав файл .env.local . Этот файл не хранится в репозитории, поэтому изначально игнорируется в .gitignore .
Никогда не храните конфиденциальную информацию в этих файлах. Позже мы рассмотрим, как управлять такими видами данных.
Логирование всех действий¶
По умолчанию возможности отладки и логирования ограничены в новых проектах. Давайте добавим дополнительные инструменты, которые помогут нам в решении проблем как в процессе разработке, так и в продакшене:
Установим инструменты отладки только в окружении разработчика:
Изучение средств отладки Symfony¶
При обновлении главной страницы в нижней части экрана должна появиться панель отладки:
Первое, на что вы, скорее всего, обратите внимание — надпись 404 на красном фоне. Помните, это просто страница-заглушка, поскольку мы ещё не определили домашнюю страницу. И даже если эта страница достаточно хорошо выглядит, она всё ещё остаётся страницей ошибки. Так что правильный код статуса HTTP для этой страницы — 404, а не 200. Благодаря панели отладки, вы сразу же получите всю необходимую информацию.
Нажмите на маленький восклицательный знак и вы увидите сообщение «настоящего» исключения в логах профилировщика Symfony. Если вы хотите увидеть трассировку стека, нажмите на ссылку «Exception» в левом меню.
Когда возникает проблема с кодом, вы увидите похожую страницу об ошибке со всей необходимой информацией для отладки:
Уделите немного времени и поизучайте данные в профилировщике Symfony, нажимая по разным ссылкам.
Логи весьма полезны при отладке. В Symfony есть удобная команда для отображения последних строк всех логов (веб-сервера, PHP и вашего приложения):
Проведем небольшой эксперимент. Откройте public/index.php и сделайте ошибку в PHP-коде (например, добавьте foobar посередине кода). Обновите страницу в браузере и понаблюдайте за логом:
Логи отображаются разными цветами, чтобы привлечь ваше внимание к ошибкам.
Symfony-функция dump() — ещё один замечательный помощник во время отладки. Она глобально доступна и отображает значение переменных в удобном интерактивном формате.
Временно измените файл public/index.php , чтобы вывести объект Request:
После обновления страницы обратите внимание на новую иконку с мишенью. Она позволит вам посмотреть детали объекта. Щёлкните по ней, чтобы перейти на отдельную страницу с полной информацией об объекте:
Отмените это изменение кода перед коммитом других изменений, которые были сделаны на этом шаге:
Настройка среды разработки¶
В локальном окружении разработки при генерации исключения Symfony отображает страницу с сообщением исключения и его трассировкой. К отображаемому пути файла в трассировке добавляется ссылка, кликнув на которую можно открыть файл на нужной строке прямо в вашей IDE. Но чтобы воспользоваться этой возможностью, сначала вам нужно настроить IDE. Symfony поддерживает множество разных IDE; я использую Visual Studio Code для данного проекта:
Ссылка в имени файла появляется не только при генерации исключения. Так, например, контроллер на панели отладки может стать кликабельным, если настроить IDE.
Отладка в продакшене¶
Отладка на продакшен-серверах всегда сложнее. К примеру, в таком случае у вас нет доступа к профилировщику Symfony. А в логах не так много подробной информации. Но всё же можно посмотреть последние записи логов:
Вы даже можете подключиться через SSH из веб-контейнера:
Не бойтесь — вы не сможете так просто всё сломать. Большая часть файловой системы доступна только для чтения. Поэтому сделать срочное исправление прямо на продакшене не получится. Однако вы узнаете про гораздо более подходящий способ сделать это позже в книге.
- « Previous Шаг 4: Выбор методологии разработки
- Next » Шаг 6: Создание контроллера
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.
Источник
Маршрутизация¶
Когда ваше приложение получает запрос, оно вызывает действие контроллера 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 , чтобы ограничить глаголы, на которые долшжен реагировать каждый маршрут:
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/
Имя переменной части (
Маршруты могут определять любое количество параметров, но каждый из них может быть использовать только единожды в каждом маршруте (например, /blog/posts-about-
Валидация параметров¶
Представьте, что ваше приложение имеет маршрут blog_show (URL: /blog/
Если пользователь запрашивает /blog/my-first-post , оба маршрута совпадут, и Symfony будет использовать маршрут, который был определен первым. Чтобы исправить это, добавьте некоторую валидацию к параметру
Опция requirements определяет `регулярные PHP-выражения`_ , которым должны соответствовать параметры маршрута для того, чтобы совпадал весь маршрут. В этом примере, \d+ — это регулярное выражение, которое совпадает с однозначным числом любой длины. Теперь:
| URL | Маршрут | Параметры |
|---|---|---|
| /blog/2 | blog_list | $page = 2 |
| /blog/my-first-post | blog_show | $slug = my-first-post |
Требования маршрута (и путей маршрута) могут включать в себя параметры контейнера , что полезно для определения сложных регулярных выражений единожды и повторного их использования во многих маршрутах.
Параметры также поддерживают свойства PCRE Unicode, которые являются последовательностями экранирования, совпадаюшими с общими типами символов. Например, \p
При использовании регулярных выражений в параметрах маршрута, вы можете установить опцию маршрута utf8 как true , чтобы сделать так, чтобы любой символ . совпадал с любым символом UTF-8, а не только с одним битом.
Если вы хотите, требования можно встроить в каждый параметр, используя синтаксис
Необязательные параметры¶
В предыдущем примере, URL blog_list — /blog/
Вы также можете сделать так, чтобы blog_list снова совпадал, когда пользователь посещает /blog , добавив значение по умолчанию к параметру
Теперь, когда пользователь посещает /blog , маршрут blog_list будет совпадать, а $page по умолчанию будет иметь значение 1 .
Вы можете иметь более одного необязательного параметра (например, /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 определяет некоторые особые атрибуты с одинаковым именем (кроме нижнего подчеркивания в начале), поэтому вам может быть легче их определить:
Источник