PHP:如何为traits中的属性提供非原始默认值?
有没有办法为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
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(…)
符号:)+我很乐意,但我会再开放一段时间。