Как настроить 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, но это тоже можно реализовать по-разному.