【问题标题】:Dependency injection in PHP traitsPHP 特征中的依赖注入
【发布时间】:2016-08-10 15:26:58
【问题描述】:

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

特质类

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

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

使用 trait 的类

namespace Frame\Slick\Block;

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

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

【问题讨论】:

  • 您使用的是哪个框架?这真的取决于它是如何实现依赖注入的。
  • 我正在使用 magento 2
  • 哪个是zend framework 3之上的平台

标签: php magento dependency-injection traits magento2


【解决方案1】:

是的,他们在编译级别“粘贴”了来自 ​​trait 的代码。考虑以下代码。它按预期工作并回显正确的值。你的问题在别处。

<?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();

代码将回显“测试”。 Working fiddle

【讨论】:

  • 但是你根本没有进行依赖注入
  • 我已经用对象编辑了它,但它与对象相同。 BTW 字符串变量也是依赖。
  • @VentzyKunev 只需添加as,然后重载构造函数并调用别名方法,它也会正常工作
【解决方案2】:

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

<?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
)

这表明框架可以使用反射来确定是否注入依赖,构造函数在特征中的事实无关紧要。

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

我还建议您通过他们的dependency injection documentation 阅读有关依赖注入在 magento 中的工作原理

【讨论】:

    【解决方案3】:

    不要使用构造函数!

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

    【讨论】:

      猜你喜欢
      • 2012-07-13
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多