PHP 特征中的依赖注入

Dependency injection in PHP traits

traits 真的可以与依赖注入一起使用吗?考虑以下代码:

特质Class

namespace Frame\Slick\Block;
use Frame\Slider\Slick\Block\Data as Helper

trait Slick
{
   protected $_slickHelper;
   public function __construct(Helper $slickHelper) 
   {
     $this->_slickHelper = $slickHelper;
   }
}

Class 使用特征

namespace Frame\Slick\Block;

class Product ListProduct implements BlockInterface 
{
   use Slick;
   public function testTrait()
   {
      return $this->_slickHelper->getHelloWorld();
   }
}

这似乎总是 return 无效,我非常确定所有内容都已正确包含。 trait 真的可以支持依赖注入吗?

是的,他们使用 trait 的代码在编译级别上是 "pasted"。考虑以下代码。它按预期工作并回显适当的值。你的问题在别处。

<?php
class Dependency
{
    public function foo()
    {
        return 'test';
    }
}

trait Slick
{
   protected $dep;

   public function __construct(Dependency $dep) 
   {
       $this->dep = $dep;
   }
}

class Product 
{
   use Slick;

   public function testTrait()
   {
      return $this->dep->foo();
   }
}

echo (new Product(new Dependency()))->testTrait();

代码将回显 'test'。 Working fiddle

一个正确实现的框架应该能够对特征构造函数进行依赖注入。通常,符合注入条件的参数是使用反射来确定的。考虑以下示例:

<?php 

class D {}

trait T {

    public function __construct(D $d) { }


}

class A {

use T;

}


$cls = new ReflectionClass("A");

$ctor = $cls->getConstructor();

print_r($ctor->getParameters()[0]->getClass());

打印:

ReflectionClass Object
(
    [name] => D
)

这表明框架可以通过反射来判断是否注入依赖,构造函数在trait中并不重要。

如果 magento 中没有发生这种情况,那么我建议您将其移至他们的建议线程(如果有)。

我还建议您通过 dependency injection documentation

阅读依赖注入在 magento 中的工作原理

不要使用构造函数!

trait SomeTrait
{

    /**
     * @var ParameterBagInterface
     */
    protected $envParams;

    /**
     * @required
     *
     * @param ParameterBagInterface $envParams
     */
    public function setFormFactory(ParameterBagInterface $envParams)
    {
        $this->envParams = $envParams;
    }
}