Symfony __construct использование - PullRequest
0 голосов
/ 04 июня 2018

Я относительно новичок в Symfony (версия 4) и пытаюсь реализовать метод __construct для внедрения зависимостей.

В настоящее время я «внедряю» зависимости через свою собственную реализацию (до того, как я узнал о методе __construct), например:

rout.yaml

fetch:
    path: /fetch/{req}
    controller: App\Controller\Fetch::init
    requirements:
    req: ".+"

/ fetch route вызывает метод init(), который служит конструктором.

Класс контроллера

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

use App\Services\Utilities; // a bunch of useful functions

class Fetch extends BaseController {

    private $u;

    public function init(Utilities $u) {

        $this->u = $u; // set the $u member with an instance of $u
    }

    private function do_fetch(){

        $this->u->prettyprint('hello service'); // use one of $u's methods
    }
}

Если вы хотите меня потворствовать, я придумал эту специальную схему до чтения документы , которые подробно описывают это (я получаю печенье).

Единственное отличие состоит в том, что документы используют __construct() вместо моего init() метода.Ниже приведен пример со страницы документа, на которую ссылаются выше:

// src/Service/MessageGenerator.php

use Psr\Log\LoggerInterface;

class MessageGenerator
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function getHappyMessage()
    {
        $this->logger->info('About to find a happy message!');
        // ...
    }
}

Но когда я заменяю init() на __construct() и обновлял route.yaml, я получаю сообщение об ошибке.

// .....

class Fetch extends BaseController {

    private $u;

    public function __construct(Utilities $u) {

        $this->u = $u; // set the $u member with an instance of $u
    }
    // ....

fetch:
    path: /fetch/{req}
    controller: App\Controller\Fetch::__construct
    requirements:
    req: ".+"

error

Требуется указать аргумент для __construct, поскольку этот метод принимает один ($u), но это было не случай, когда init() действовал как конструктор.

Более того, я чувствую, что поскольку метод __construct() является встроенным хуком, Symfony должен знать, как его использовать, без необходимости явно указывать его в route.yaml.Однако, исключая это, выдает ошибку.

rout.yaml (__construct явно не указано)

fetch:
    path: /fetch/{req}
    controller: App\Controller\Fetch
    requirements:
    req: ".+"

enter image description here

Чего мне здесь не хватает

1 Ответ

0 голосов
/ 05 июня 2018

__construct - магический метод в PHP.Проблема с вашим init методом состоит в том, что он не требует, чтобы объект должен иметь экземпляр объекта, который вам нужен для построения.Иногда свойство объекта не требуется.В этом случае я рекомендую создать setter как способ необязательного задания этого свойства. Попробуйте сделать ваши свойства класса закрытыми и разрешать только их мутирование или извлечение через установщики и получатели ... это будетобеспечить стандартный API для вашего объекта и избежать случайных манипуляций с состоянием.

Вы можете использовать DIC в маршрутизаторе Symfony для создания вашего контроллера вместо расширения базового класса контроллеров путем регистрации ваших контроллеров в качестве сервисов .Это значительно разъединяет ваш код и обеспечивает все виды дополнительной гибкости.Вы всегда должны отдавать предпочтение композиции, а не наследованию.

...