Почему создание класса динамических объектов ths php не работает?

Я пытаюсь создать класс (работающий как фабричный класс) в своем приложении Zend Expressive следующим образом:

declare(strict_types=1);

namespace App\Install\Factory;

use App\Install\Model as Models;
use App\Install\Abstracts\AttributeInterface;

class AttributeEntityFactory{

    public static function create($type1 ='Attribute') : AttributeInterface
    {
        $resolvedClass = "Models\\$type1";
        $resolvedClass1 = 'Models\\'.$type1;
        //return new $resolvedClass();
        //return new $resolvedClass1();
        return new Models\Attribute();
    }
}

Приведенный выше код отлично работает для меня. Однако, если попытаться использовать любой из двух других операторов возврата, он показывает

Класс «Модели\Атрибут» не найден

Как я могу добиться динамического создания экземпляра?

Код класса атрибута выглядит следующим образом:

namespace App\Install\Model;
use App\Install\Abstracts\AttributeInterface;

class Attribute implements AttributeInterface
{
    protected $attribute;

    public function setAttribute($attribute)
    {
        $this->attribute = $attribute;
    }

    public function getAttribute()
    {
        return $this->attribute;   
    }  
}

Моя версия PHP:

PHP 7.2.13 (cli) (построено: 14 декабря 2018 г., 04:20:16) (NTS)


person Md Monjur Ul Hasan    schedule 26.02.2019    source источник


Ответы (2)


вам может понадобиться передать полное пространство имен?

"App\Install\Model\" . $type1;

и более...

Атрибут модели, который у вас есть, находится в пространстве имен App\Install\Model, а объект, который вы пытаетесь создать, находится в пространстве имен Models\\ . $type1.

возможно, вам нужно изменить Models на Model

person Drakulitka    schedule 27.02.2019

Лично я бы избегал такой фабричной реализации по нескольким причинам:

  1. Это связано с магией.
  2. Менее предсказуемый код.
  3. Труднее читать как для людей, так и для IDE (например, PHPStorm не найдет использование класса Attribute в таком коде, когда вам нужно его найти)
  4. Сложнее анализировать с помощью статических анализаторов

Вместо этого я бы переписал это в более явную фабрику, даже если бы у меня были десятки разных классов в пространстве имен App\Install\Model:

<?php declare(strict_types=1);

namespace App\Install\Factory;

use App\Install\Model as Models;

class AttributeEntityFactory
{
    public static function create($type = 'Attribute') : AttributeInterface
    {
        switch ($type) {
            case 'Attribute':
                return new Models\Attribute();
            case 'SomethingElse':
                return new Models\SomethingElse();
            default:
                throw new \InvalidArgumentException(
                    sprintf('An unknown type %s requested from %s', $type, __METHOD__)
                );
        }
    }
}

Как правило большого пальца:

  • Никогда не составляйте имена классов/пространства имен, используя строки, соединенные с переменными/параметрами/константами.
  • Никогда не вызывайте методы таким образом.

Вы поблагодарите меня, когда ваше приложение/бизнес/кодовая база вырастет достаточно.

person edigu    schedule 10.03.2019