Согласно вашему образцу на 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-ссылку в конструктор, но я не смог бы вызвать установщик, потому что 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 а также setLogger
метод через LoggerAwareTrait
public function __construct(LoggerInterface $logger = null)
{
$this->setLogger($logger);
}
Если ваш конструктор принимает ноль, вы не должны вызывать setLogger
метод. setLogger
метод может принимать только LoggerInterface
и он не должен случайно устанавливать объект логгера на ноль сам.
Допустим, подпись была setLogger($logger = null)
, Теперь, если вы позвоните setLogger()
как в примере ниже, вы можете увидеть, что логгер будет сброшен на ноль.
$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
Надеюсь, это поможет.
Спасибо.
Других решений пока нет …