Symfony 5.1 - Не удается автоматически подключить сервис

Я хочу рефакторить свой код, но теперь у меня ошибка, и я не понимаю, что. Objectif : не нужно передавать параметры при вызове TokenService и использовать автоматическое подключение для автоматического подключения EntityManager & Request и не устанавливать его при вызове службы контроллера.

Не удается разрешить аргумент $tokenService для App\Controller\TokenController::showTokens() Не удается выполнить автоподключение службы App\Service\TokenService аргумент $request метода __construct() ссылается на класс Symfony\Component\HttpFoundation\Request, но такой службы не существует.

До :

/src/Контроллер/TokenController.php

<?php

namespace App\Controller;

use App\Service\TokenService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/v1")
 */
class TokenController
{
   /** @var EntityManagerInterface $em */
    private $em;
    /** @var Request $request */
    private $request;

    /**
     * TokenService constructor.
     *
     * @param Request $request
     * @param EntityManagerInterface $em
     */
    public function __construct(Request $request, EntityManagerInterface $em)
    {
        $this->request = $request;
        $this->em = $em;
    }

    public function showTokens(Request $request, EntityManagerInterface $em): JsonResponse
    {
        $tokenService = new TokenService($request, $em);

        return $tokenService->getTokens();
    }
}

/src/Сервис/TokenService.php

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Class TokenService
 * @package App\Service
 */
class TokenService
{
    /** @var EntityManagerInterface $em */
    private $em;
    /** @var Request $request */
    private $request;

    /**
     * TokenService constructor.
     *
     * @param Request $request
     * @param EntityManagerInterface $em
     */
    public function __construct(Request $request, EntityManagerInterface $em)
    {
        $this->request = $request;
        $this->em = $em;
    }

    public function getTokens()
    {
        return true;
    }
}

После :

/config/services.yaml

parameters:

services:
    _defaults:
        autowire: true
        autoconfigure: true

    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'

    App\Controller\:
        resource: '../src/Controller/'
        tags: ['controller.service_arguments']

    App\Service\TokenService: ~

/src/Контроллер/TokenController.php

<?php

namespace App\Controller;

use App\Service\TokenService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/v1")
 */
class TokenController
{
    public function showTokens(Request $request, EntityManagerInterface $em, TokenService $tokenService): JsonResponse
    {
        return $tokenService->getTokens();
    }

/src/Сервис/TokenService.php

<?php

namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
 * Class TokenService
 * @package App\Service
 */
class TokenService
{
    /** @var EntityManagerInterface $em */
    private $em;
    /** @var Request $request */
    private $request;

    /**
     * TokenService constructor.
     *
     * @param Request $request
     * @param EntityManagerInterface $em
     */
    public function __construct(Request $request, EntityManagerInterface $em)
    {
        $this->request = $request;
        $this->em = $em;
    }

    public function getTokens()
    {
        return true;
    }
}

Спасибо !

symfony.com/doc/current/service_container/request.html Убедитесь, что понимаете, почему вы внедряете стек запроса вместо запроса.
Cerad 20.12.2020 18:24

Это для примера! Запрос используется после обслуживания, у меня есть простой код, чтобы не усложнять ситуацию. У меня есть запись objectif и ошибка

Sigri44 20.12.2020 18:28

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

Cerad 20.12.2020 18:32

Я думаю, мы не понимаем друг друга. Я могу очень хорошо получить запрос в службе, так как он передается в качестве аргумента при создании экземпляра в контроллере. За исключением того, что я считаю бесполезным в контроллере, для всех вызовов, сделанных в эту службу, систематически предоставлять Request/EntityManager, поэтому я хочу пройти через внедрение зависимостей, чтобы оба можно было использовать из службы, не имея предоставить их во время создания экземпляра.

Sigri44 20.12.2020 18:35

Вы правы в том, что мы явно не понимаем друг друга. Что хорошо. Может быть, кто-то еще придет. Но мне очень любопытно, как вы думаете, что сообщение об ошибке: «Не удается автоматически подключить сервис App\Service\TokenService аргумент $request метода __construct()» означает, что вы успешно внедрили службу запроса? Тем более, что нет службы запросов. Ваш контроллер, конечно же, должен выполнять return $tokenService->getTokens($request); но это почти не имеет значения.

Cerad 20.12.2020 18:42

Возможно, это поможет: symfony.com/blog/new-in-symfony-2-4-the-request-stack

Cerad 20.12.2020 18:44

Хорошо, я понял свою ошибку! Я использовал ваш ответ, и он отлично работает. Используйте RequestStack и удалите все «аргументы запроса» в контроллере, и служба будет нормально работать с autowire! Вы можете использовать его (и документы) на ответе, и я поддерживаю вас, чтобы решить эту проблему! Спасибо

Sigri44 20.12.2020 18:46
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
7
6 118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, прошло некоторое время с тех пор, как у нас был хороший вопрос о стеке запросов. Я немного поискал и не нашел ответа, который был бы непосредственно применим и дал достойное объяснение.

Основная проблема заключается в том, что среда Symfony поддерживает вложенные запросы. Вы получаете их, например, при использовании встроенных контроллеров. Таким образом, нет фактической службы запросов. На самом деле это было, когда Symfony 2.0 был впервые выпущен, но это был настоящий беспорядок. Поддержка сервисов вложенных запросов выполнялась на уровне контейнера, и это было неинтересно.

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

class TokenService
{
    private $em;
    private $requestStack;

    public function __construct(RequestStack $requestStack, EntityManagerInterface $em)
    {
        $this->requestStack = $requestStack;
        $this->em = $em;
    }

    public function getTokens()
    {
        $request = $this->requestStack->getMasterRequest(); // or possibly getCurrentRequest depending on where the tokens are
        return true;
    }

Сказав это, я бы лично просто передал запрос от контроллера. Это избавит меня от моего комментария «это зависит». Я также думаю, что это немного уменьшает задействованную «магию». Оба подхода будут работать.

class TokenService
{
    public function getTokens(Request $request)
    {
        return true;
    }
...
class TokenController
{
    public function showTokens(Request $request, TokenService $tokenService): JsonResponse
    {
        return $tokenService->getTokens($request);
    }

Другие вопросы по теме