Как настроить Symfony роутер для передачи ```{slug}``` вместо ```Id``` и правильно связать сущность ```Page``` с контроллером, чтобы не возникало ошибок "Cannot autowire argument $page of "App\Controller\PageController::show()""?
Для использования slug в Symfony, сначала необходимо настроить роутер для передачи slug вместо id. Для этого нужно в конфигурации маршрутов routes.yaml указать параметр {slug} вместо {id}. Например: ```yaml page_show: path: /page/{slug} controller: App\Controller\PageController::show defaults: _controller: 'App\Controller\PageController::show' ``` Далее, необходимо в контроллере PageController правильно связать сущность Page с полученным slug. Для этого можно воспользоваться Doctrine EntityManager для получения записи Page по slug. Например: ```php namespace App\Controller; use App\Entity\Page; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; class PageController extends AbstractController { public function show(Page $page): Response { // Ваш код для отображения страницы } } ``` При этом не забудьте добавить аннотацию ```@ParamConverter``` к параметру метода show, чтобы Symfony могла автоматически преобразовать slug в объект Page. ```php use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; /** * @ParamConverter("page", options={"mapping": {"slug": "slug"}}) */ public function show(Page $page): Response { // Ваш код для отображения страницы } ``` Таким образом, можно использовать slug в Symfony и правильно связать сущность Page с контроллером, чтобы избежать ошибок "Cannot autowire argument $page of "App\Controller\PageController::show()"".
public function show(Request $request, Page $page): Response
Здесь symfony пытается заполнить атрибуты объекта Page, основываясь на значениях из запроса. В запросе есть только slug. Если бы в Page остальные атрибуты были необязательные у них были заполнены значения по умолчанию, то сущность Page заполнялась бы slug'ом из запроса и этими значениями по умолчанию, и именно этот объект был бы в контроллере, без ошибок.
Очевидно, что такое поведение не ожидается при попытке найти сущность по slug.
Правильный подход:
В методах контроллера ожидают DTO запроса и на основе этого DTO получают сущность
class ShowPageRequestDTO { public function __construct( public readonly string $slug, ) {} } class PageController { public function __construct( private readonly PageRepository $repository, ) {} public function show(ShowPageRequestDTO $request) { return $this->render('/page/show.html.twig', [ 'slug' => $request->slug, 'page' => $this->repository->findBySlug($request->slug), ]); } }
В данном примере опущена валидация запроса, т.к. ее можно осуществить по-разному, а так же указан некий PageRepository с методом findBySlug для получения сущности из базы по slug, но это тоже можно реализовать по-разному.