PHP构造函数和依赖关系的简写

时间:2013-06-10 14:16:19

标签: php dependency-injection soa

随着越来越多的面向服务的PHP正在进行中,我发现自己有很多PHP文件,这些文件只有初始化的长代码。在其他语言(如C ++或typescript)中,您可以执行以下操作而无需复制。一个PHP示例:

namespace Test\Controllers;
use Test\Services\AppleService;
use Test\Services\BananaService;
use Test\Services\PearService;
use Test\Services\LemonService;
use Test\Services\PeachService;

class TestController{

    protected $appleService;
    protected $bananaService;
    protected $lemonService;
    protected $pearService;
    protected $peachService;

    public function __construct(
    AppleService $appleService,
    BananaService $bananaService,
    LemonService $lemonService,
    PearService $pearService,
    PeachService $peachService
    ){
        $this->appleService = $appleService;
        $this->bananaService = $bananaService;
        $this->lemonService = $lemonService;
        $this->pearService = $pearService;
        $this->peachService = $peachService;
    }
}

打字稿示例:

module namespace Test.Controllers {
    export class TestController{
        constructor(
        private appleService:Test.Services.AppleService,
        private bananaService:Test.Services.BananaService,
        private lemonService:Test.Services.LemonService,
        private pearService:Test.Services.PearService,
        private peachService:Test.Services.PeachService
        ){}
    }
}

是否有更好/更短的方法来做同样的事情,和/或是否有任何支持使这个更容易计划用于即将发布的PHP版本?

2 个答案:

答案 0 :(得分:0)

还有另一种属性注入:

use DI\Annotation\Inject;

class TestController
{
    /**
     * @Inject
     * @var AppleService
     */
    private $appleService;
    /**
     * @Inject
     * @var BananaService
     */
    private $bananaService;
    /**
     * @Inject
     * @var LemonService
     */
    private $lemonService;
    /**
     * @Inject
     * @var PearService
     */
    private $pearService;
    /**
     * @Inject
     * @var PeachService
     */
    private $peachService;
}

这是更短,还是更简单?我会让你判断的。但我喜欢它,我最终没有一个臃肿的构造函数。这是受到Java / Spring FYI的启发。

现在这个例子适用于PHP-DI(免责声明:我正在研究它),但可能有其他DI容器提供相同的功能。

警告:属性注入无处不在。

我发现它适用于控制器(因为控制器不应该被重用)。 Read more here

我不认为在服务中使用它是合适的。所以这不是最终的解决方案。

答案 1 :(得分:0)

这种语法糖最终将在PHP 8.0中发布(2020年11月26日)。

通过在构造函数中使用publicprotectedprivate作为参数的前缀,它们将被复制并定义为具有相同名称的类属性。

在PHP 8.0中,OP的示例可以写为:

namespace Test\Controllers;

use Test\Services\AppleService;
use Test\Services\BananaService;
use Test\Services\PearService;
use Test\Services\LemonService;
use Test\Services\PeachService;

class TestController{

   public function __construct(
       protected AppleService $appleService,
       protected BananaService $bananaService,
       protected LemonService $lemonService,
       protected PearService $pearService,
       protected PeachService $peachService
   ){
   }
}

https://wiki.php.net/rfc/constructor_promotion

https://stitcher.io/blog/constructor-promotion-in-php-8