Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/238.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP:如何为traits中的属性提供非原始默认值?_Php_Dependency Injection_Traits - Fatal编程技术网

PHP:如何为traits中的属性提供非原始默认值?

PHP:如何为traits中的属性提供非原始默认值?,php,dependency-injection,traits,Php,Dependency Injection,Traits,有没有办法为traits中的属性提供默认对象 trait myTrait{ private $foo = 0; // works private $bar = new stdClass(); // doesn't work. } 我知道,将具体对象实例化为默认值(由于高度耦合)似乎是一种糟糕的编码方式。这里的想法是为可选依赖项提供一个 示例用例 一个更好的例子(我目前正在考虑的例子): 使用Trait进行日志记录,并实现as default属性的默认NullLogger: trait

有没有办法为traits中的属性提供默认对象

trait myTrait{
  private $foo = 0; // works
  private $bar = new stdClass(); // doesn't work.
}
我知道,将具体对象实例化为默认值(由于高度耦合)似乎是一种糟糕的编码方式。这里的想法是为可选依赖项提供一个

示例用例 一个更好的例子(我目前正在考虑的例子):

使用Trait进行日志记录,并实现as default属性的默认
NullLogger

trait LoggerTrait{
  /**
    * @var Psr\Log\LoggerInterface
    */
  protected $logger;

  public function setLogger(Psr\Log\LoggerInterface $logger){
    $this->logger = $logger;
  }
}

class Foo{
  use LoggerTrait;

  public function __construct(){
    $this->setLogger(new Psr\Log\NullLogger()); // I would like to avoid this line as I'd need to duplicate it in every class I'm using the LoggerTrait.
  }

  public function doStuff(){
    $this->logger->info("Yey flexible logging with no overhead!");
  }

}
这是可行的,但是我必须在每个使用trait的类中显式地设置
NullLogger
,我希望避免这种“代码重复”


PS:我相信有人会提出,记录器也可以通过DI容器插入。这是真的,但我不是真的需要。有关一些赞成/反对的参数,请参见此:)

解决此问题的常见方法是在类中使用
getter
,即使该类拥有该属性

trait LoggerTrait{
    /**
     * @var Psr\Log\LoggerInterface
     */
    protected $logger;

    public function setLogger(Psr\Log\LoggerInterface $logger){
        $this->logger = $logger;
    }

    public function getLogger()
    {
        if(null === $this->logger) {
            $this->logger = new Psr\Log\NullLogger();
        }

        return $this->logger;
    }
}
这样,直到需要时才实例化默认对象

class Foo{
    use LoggerTrait;

    public function doStuff(){
        $this->getLogger()->info("Yey flexible logging with no overhead!");
    }
}

IIRC即使使用常规属性也不能这样做。trait实际上成为它们所使用的类的一部分,有点像预编译过程。看起来是一种合适的方法,尽管我不太喜欢
$this->getLogger()->info(…)
符号:)+我很乐意,但我会再开放一段时间。