PSR Log - почему нет значения NULL по умолчанию для LoggerAwareInterface и LoggerAwareTrait

Согласно вашему примеру на Github вы вводите интерфейс logger в конструктор со значением по умолчанию 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);
}

Поэтому, пожалуйста, расскажите мне об этом решении?

1 ответ

Решение

Я думаю, что вы смешиваете много вопросов здесь.

Пример использования https://github.com/php-fig/log показывает, как вы можете использовать psr/log реализация в вашем приложении. Это делает это правильно тоже.

Так что следующий вопрос об использовании LoggerAwareInterface и setLogger метод через LoggerAwareTrait

public function __construct(LoggerInterface $logger = null)
{
    $this->setLogger($logger);
}

Если ваш конструктор принимает ноль, вы не должны вызывать setLogger метод. setLogger метод может принимать только LoggerInterface и ему не нужно случайно устанавливать для объекта logger значение null.

Допустим, подпись была 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

Надеюсь, это поможет.

Спасибо.

Другие вопросы по тегам