4

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\LoggerAwareInterfacePsr\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);
}

では、この決定の背景を教えてください。

4

1 に答える 1