PSR 日志 - 为什么 LoggerAwareInterface 和 LoggerAwareTrait 没有 NULL 默认值
PSR Log - Why no NULL default value for LoggerAwareInterface and LoggerAwareTrait
根据您在 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
}
}
表示某物具有您可以实现的 Logger Psr\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 引用传递给构造函数,但我不可能调用 setter 因为 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);
}
所以请告诉我这个决定的背景?
我认为你在这里混淆了很多问题。
示例用法 https://github.com/php-fig/log#usage 展示了如何在您的应用程序中使用 psr/log
实现。它也做对了。
所以下一个问题是关于LoggerAwareInterface and setLogger
method via the LoggerAwareTrait
的用法
public function __construct(LoggerInterface $logger = null)
{
$this->setLogger($logger);
}
如果您的构造函数接受 null,则不应调用 setLogger
方法。 setLogger
方法只能接受 LoggerInterface
并且它不会意外地需要将记录器对象设置为 null 本身。
假设签名为setLogger($logger = null)
。现在,如果您像下面的示例那样调用 setLogger()
,您可以看到记录器将重置为 null。
$logger = new SomePSR-3Logger();
$foo = new Foo($logger);
$foo->setLogger();
如果你想实现 PSR-3 记录器,你应该考虑阅读:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
希望对您有所帮助。
谢谢。
根据您在 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
}
}
表示某物具有您可以实现的 Logger Psr\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 引用传递给构造函数,但我不可能调用 setter 因为 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);
}
所以请告诉我这个决定的背景?
我认为你在这里混淆了很多问题。
示例用法 https://github.com/php-fig/log#usage 展示了如何在您的应用程序中使用 psr/log
实现。它也做对了。
所以下一个问题是关于LoggerAwareInterface and setLogger
method via the LoggerAwareTrait
public function __construct(LoggerInterface $logger = null)
{
$this->setLogger($logger);
}
如果您的构造函数接受 null,则不应调用 setLogger
方法。 setLogger
方法只能接受 LoggerInterface
并且它不会意外地需要将记录器对象设置为 null 本身。
假设签名为setLogger($logger = null)
。现在,如果您像下面的示例那样调用 setLogger()
,您可以看到记录器将重置为 null。
$logger = new SomePSR-3Logger();
$foo = new Foo($logger);
$foo->setLogger();
如果你想实现 PSR-3 记录器,你应该考虑阅读:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
希望对您有所帮助。
谢谢。