PHP-DI: интерфейс, внедряемый в конструктор, не будет корректно разрешаться

Кажется, я не могу заставить PHP-DI правильно разрешить интерфейс для настроенного класса при введении в конструктор. В следующем коде использование контейнера для получения \Foo\IDog возвращает класс Poodle, но при использовании контейнера для получения \Foo\Kennel (у которого есть \Foo\IDog в конструкторе, он больше не распознает, что он настроен на верните пуделя и ошибки, говоря:

"Entry "\Foo\Kennel" cannot be resolved: Entry "Foo\IDog" cannot be resolved: the class is not instantiable"

Вот доказательство концепции:

<?php
namespace Foo;

require(__DIR__ . "/vendor/autoload.php");

interface IDog {
    function bark();
}

class Poodle implements IDog {
    public function bark() {
        echo "woof!" . PHP_EOL;
    }
}

class Kennel {
    protected $dog;
    public function __construct(\Foo\IDog $dog) {
        $this->dog = $dog;
    }

    public function pokeDog() {
        $this->dog->bark();
    }
}

$containerBuilder = new \DI\ContainerBuilder();
$containerBuilder->addDefinitions([
    "\Foo\IDog" => \DI\autowire("\Foo\Poodle")
]);
$container = $containerBuilder->build();

//Works:
$mydog = $container->get("\Foo\IDog");
$mydog->bark();

//Does not work:
$kennel = $container->get("\Foo\Kennel");
$kennel->pokeDog();

Странно то, что он отлично работает, если я удаляю из него все пространства имен (вот оно без пространства имен: https://gist.github.com/brentk/51f58fafeee8029d7e8b1e838eca3d5b).

Любая идея, что я делаю неправильно?


person Brent    schedule 21.08.2018    source источник


Ответы (1)


Я думаю, это потому, что ваши имена классов недействительны в вашей конфигурации: "\Foo\IDog" недопустимо, "Foo\IDog" является.

Когда в коде \Foo\IDog тоже работает, но когда в строке допустимо только Foo\IDog.

Безопасный способ избежать этого — использовать \Foo\IDog::class. Таким образом PHP сообщит вам, что класс не существует.

person Matthieu Napoli    schedule 22.08.2018
comment
Спасибо, переключение всех экземпляров, где тип упоминался как строка, например "Foo/Bar", на /Foo/Bar::class помогло. - person Brent; 22.08.2018