Почему создание класса динамических объектов 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();
}
}
Приведенный выше код отлично работает для меня. Однако, если попытаться использовать любой из двух других операторов возврата, он показывает
Класс '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)
1 ответ
Лично я бы избегал такой заводской реализации по нескольким причинам:
- Это связано с магией.
- Менее предсказуемый код.
- Труднее читать как для людей, так и для IDE (например, PHPStorm не нашел бы использования
Attribute
класс в таком коде, когда нужно его найти) - Сложнее анализировать с помощью статических анализаторов
Вместо этого я бы переписал это на более явную фабрику, даже если бы у меня были десятки разных классов в 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__)
);
}
}
}
Как правило большого пальца:
- Никогда не сочиняйте имена классов / пространства имен, используя строки, связанные с переменными / параметрами / константами.
- Никогда не вызывайте методы таким способом тоже.
Вы будете благодарить меня, когда ваше приложение / бизнес / кодовая база вырастет достаточно.
Вам может понадобиться пройти в полном пространстве имен?
"App\Install\Model\" . $type1;
и больше...
Атрибут модели у вас есть в пространстве имен App\Install\Model
и объект, который вы пытаетесь создать, Models\\ . $type1
может быть, вам нужно изменить Models
в Model