Статический фабричный метод PHP: динамически создавать экземпляр вызывающего класса

Этот вопрос PHP связан с этот вопрос, но немного по-другому. У меня есть статический метод фабрики под названием create() который создает экземпляр класса. Я хочу, чтобы метод динамически создавал экземпляр класса (под), в котором он вызывается. Таким образом, класс, который он создает, должен быть определен во время выполнения. Но я хочу сделать это без переопределения статического метода фабрики в подклассе (и это было бы совершенно справедливо в моем примере, так как у подкласса нет новых элементов данных для инициализации). Это вообще возможно?

class Foo {

private $name;

public static function create($name) {

//HERE INSTED OF:
return new Foo($name);
//I WANT SOMETHING LIKE:
//return new get_class($this)($name);//doesn't work
//return self($this);//doesn't work either

}

private function __construct($name) {

$this->name = $name;

}

public function getName() {

return $this->name;

}

}

// the following class has no private data, just extra methods:

class SubFoo extends Foo {

public function getHelloName() {

echo "Hello, ", $this->getName(), ".\n";

}

}$foo = Foo::create("Joe");
echo $foo->getName(), "\n"; // MUST OUTPUT: Joe

$subFoo = SubFoo::create("Joe");
echo $subFoo->getHelloName(), "\n"; // MUST OUTPUT: Hello, Joe.

6

Решение

Вы должны создать объект, используя Late Static Binding — метод get_called_class() Полезно. Второй вариант использования static ключевое слово.

Пример:

class Foo
{
private $name;

public static function create($name)
{
$object = get_called_class();
return new $object($name);
}

private function __construct($name)
{
$this->name = $name;
}

public function getName()
{
return $this->name;
}
}

class SubFoo extends Foo
{
public function getHelloName()
{
return "Hello, ". $this->getName();
}
}

$foo = Foo::create("Joe");
echo $foo->getName(), "\n";

$subFoo = SubFoo::create("Joe");
echo $subFoo->getHelloName(), "\n";

И вывод:

Joe
Hello, Joe
5

Другие решения

return new static();

уже зарезервировано ключевое слово static

5

Да, это возможно при поздней статической привязке php.

Вместо? из

$foo = Foo::create("Joe");
echo $foo->getName(), "\n"; // MUST OUTPUT: Joe

$subFoo = SubFoo::create("Joe");
echo $foo->getHelloName(), "\n"; // MUST OUTPUT: Hello, Joe.

попробуй это

echo parent::getName();
echo self::getHelloName();
-3
По вопросам рекламы [email protected]