Githubのサンプルによると、デフォルト値の NULL を使用してコンストラクターにロガー インターフェイスを挿入します。
<?php
use Psr\Log\LoggerInterface;
class Foo
{
private $logger;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
実装できる LoggerPsr\Log\LoggerAwareInterface
とPsr\Log\LoggerAwareTrait
.
サンプルコードを再構築すると、次のようになります
<?php
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
class Foo implements LoggerAwareInterface
{
use LoggerAwareTrait;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
それは問題なく機能していますが、私がこれを行うとしたら
<?php
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
class Foo implements LoggerAwareInterface
{
use LoggerAwareTrait;
public function __construct(LoggerInterface $logger = null)
{
$this->setLogger( $logger );
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
must be an instance of Psr\Log\LoggerInterface, null given
インターフェイスのメソッド宣言に NULL デフォルト値がないため、エラーになります。もちろん、このエラーは if でガードするか を渡すことで防ぐことができますがNullLogger
、これは非常に奇妙です。
コンストラクターでオプションの Logger インスタンスを渡すことができると、後で Logger を NULL の値に設定することでインスタンスを変更できると思います。もちろんこれはサンプルコードですが、問題を見てみましょう
public function __construct(LoggerInterface $logger = null);
public function setLogger(LoggerInterface $logger);
したがって、基本的にコンストラクターに NULL 参照を渡すことはできますが、NULL は許可されていないため、セッターを呼び出すことはできません。Psr\Log\LoggerAwareInterface
こんな感じだったらもっと良かったのに
<?php
namespace Psr\Log;
/**
* Describes a logger-aware instance.
*/
interface LoggerAwareInterface
{
/**
* Sets a logger instance on the object.
*
* @param LoggerInterface $logger
*
* @return void
*/
public function setLogger(LoggerInterface $logger = null);
}
では、この決定の背景を教えてください。