Symfony __construct用法

时间:2018-06-04 19:04:58

标签: php symfony constructor symfony4 php-7.1

我对Symfony(版本4)相对较新,并尝试实现依赖注入的__construct方法。

目前,我通过自己的实现(在我了解__construct方法之前)“注入”依赖项,如下所示:

routes.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
    }
}

如果你愿意放纵我,我会在阅读the docs之前想出这个临时方案,这几乎完全详细说明了(我得到了一个cookie)。

一个区别是文档使用__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()并更新routes.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()时,这构造函数。

此外,我觉得因为fetch: path: /fetch/{req} controller: App\Controller\Fetch requirements: req: ".+" 方法是一个内置的钩子,Symfony应该知道使用它而不必在routes.yaml中明确告诉它。但是,排除它也会引发错误。

routes.yaml(__construct未明确指出)

<cfmail
   to="someone@x.com"
   from="someone@y.com"
   subject="howdy"
   type="html">
      <cfinclude template="path/to/emailtemplates/sometemplate.htm"/>
</cfmail>

enter image description here

我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

__construct是PHP中的一种神奇方法。您的init方法的问题在于,它不强制对象必须具有您需要的对象实例才能构建。有时不需要对象属性。在这种情况下,我建议创建一个setter作为可选的设置属性的方法。尝试使您的类属性为私有,并且只允许它们通过setter和getter进行变异或检索...这将提供一个您的obejct的标准API,并避免随机状态操作。

您可以使用Symfony路由器中的DIC构建控制器,而不是将基本控制器类扩展registering your controllers as services。这极大地解耦了代码并允许各种额外的灵活性。你应该总是赞成合成而不是继承。