Почему создание класса динамических объектов php не работает? - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь создать класс (работающий как фабричный класс) в моем приложении 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();
    }
}

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

Класс '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)

Ответы [ 2 ]

0 голосов
/ 11 марта 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__)
                );
        }
    }
}

Как правило:

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

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

0 голосов
/ 27 февраля 2019

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

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

и более ...

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

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

...