PHP, передающий параметры при создании нового объекта, call_user_func_array для объектов

Я хотел бы динамически создать объект PHP, и параметры были бы необязательными.

Например, вместо этого:

$test = new Obj($param); 

Я хотел бы сделать что-то вроде этого (создать новое ob является вымышленным):

 $test = create_new_obj('Obj', $param); 

Есть ли такая функция в php? Нечто похожее на call_user_func_array, но вместо объекта.

Solutions Collecting From Web of "PHP, передающий параметры при создании нового объекта, call_user_func_array для объектов"

Начиная с PHP 5.6, вы можете достичь этого с помощью одной строки кода, используя новый оператор Argument Unpacking (…).

Вот простой пример.

 $className='Foo'; $args=['arg1','arg2','arg3']; $newClassInstance=new $className(...$args); 

Подробнее см. В списках аргументов переменной длины PHP .

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

 $r = new ReflectionClass($strClassName); $myInstance = $r->newInstanceArgs($arrayOfConstructorArgs); 

Например, если ваш конструктор Car взял 3 аргумента

 $carObj = new Car($color, $engine, $wheels); 

затем

 $strClassName = 'Car'; $arrayOfConstructorArgs = array($color, $engine, $wheels); $r = new ReflectionClass($strClassName); $carObj = $r->newInstanceArgs($arrayOfConstructorArgs); 

http://php.net/manual/en/class.reflectionclass.php
http://php.net/manual/en/reflectionclass.newinstanceargs.php

В таких случаях я использую фабричные методы. они могут быть легко определены в абстрактных классах:

 class Foobar { public function __construct($foo, $bar) { // do something } static public function factory($foo, $bar) { return new self($foo, $bar); } } 

с этим вы можете использовать call_user_func_array() :

 $my_foobar_obj = call_user_func_array('Foobar::factory', array($foo, $bar)); 

Вы можете динамически создавать объект, если знаете имя класса:

 $objName = 'myClass'; $test = new $objName($param); 

Вы можете легко определить функцию __construct() чтобы принимать аргументы по умолчанию, если это было требованием вашей логики построения.

[Редактировать заметку]: это понятие, известное как переменные переменные , и есть некоторые примеры в руководстве, где вводится новая команда.

Вот чистая версия того, что вы хотели:

 class ClassName { public static function init(){ return (new ReflectionClass(get_called_class()))->newInstanceArgs(func_get_args()); } public static function initArray($array=[]){ return (new ReflectionClass(get_called_class()))->newInstanceArgs($array); } public function __construct($arg1, $arg2, $arg3){ ///construction code } } 

Обычный уродливый метод создания нового экземпляра объекта с использованием нового

 $obj = new ClassName('arg1', 'arg2', 'arg3'); echo $obj->method1()->method2(); 

Статический вызов с использованием init вместо нового

 echo ClassName::init('arg1', 'arg2', 'arg3')->method1()->method2(); 

Статический вызов с использованием initArray вместо нового

 echo ClassName::initArray(['arg1', 'arg2', 'arg3'])->method1()->method2(); 

Основываясь на ответе @chris ( https://stackoverflow.com/a/2550465/1806628 ), это использование классов отражения:

 abstract class A{ // the constructor writes out the given parameters public function __construct(){ var_dump(func_get_args()); } public function copy(){ // find our current class' name, __CLASS__ would return A $thisClass = get_class($this); $tmp = new ReflectionClass($thisClass); // pass all the parameters recieved to the new object $copy = $tmp->newInstanceArgs(func_get_args()); return $copy; } } class B extends A{} // create a new B object, with no parameters $b = new B(); // create another b, but with other parameters $c = $b->copy('the parameter of the copied B'); 

Это полезно, если вы хотите сделать функцию копирования объекта в классе предков и не знаете, нужны ли дочерние классы в будущем, или нет.