Как динамически инициализировать класс РНР с динамическики параметрами. Вот решение.
Рассмотрим ситуацию когда нам нужно создать класс с параметрами. Условия храняться в Yaml файле.
Основная проблема кроется в неопределенном количестве параматров. Попробуем найти решение
Решение 1 : плохое.
Этот метод использует create_function для инициализации класса с необходимыми параметрами. Это решение сработает с указанием класса, а вот с параметрами работать не будет. Получите ошибку: 'Call to undefined method myClass::__set_state() in index.php : runtime-created '
Эта ошибка из-за того, что var_export пытаеться вызвать не существующий метод __set_state. Этот метод очевидно плохое решение.
Решение 2 : Некрасивое.
Мы можем ограничить максимально количество аргументов - 5. Код выглядит так:
Решение 3 : Хорошее.
call_user_function_array() - наш помошник во всех случаях.
Посмотрев глубже в возможности Reflection PHP найденно идеальное решение на данный момент.
function create_instance($class, $params) {
$reflection_class = new ReflectionClass($class);
return $reflection_class->newInstanceArgs($params);
}
Размышление можно просмотреть в полной статье.Рассмотрим ситуацию когда нам нужно создать класс с параметрами. Условия храняться в Yaml файле.
class: MyClass
params: [ "value 1", { key1: "value key 1", key2: "value key 2" ]
Так это будет выглядеть наш класс. Ну где же динамика?class myClass {
public $arg1;
public $arg2;
public function __construct($arg1, $arg2) {
$this->arg1 = $arg1;
$this->arg2 = $arg2;
}
}
$class = 'myClass';
$params = = array(
'value 1',
array('key1' => 'value key 1', 'key2' => 'value key 2')
);
$instance = new $class($params[0], $params[1]);
Основная проблема кроется в неопределенном количестве параматров. Попробуем найти решение
Решение 1 : плохое.
function create_instance($class, $params) {
$inline = array();
foreach($params as $index => $param) {
$params[$index] = var_export($param, true);
}
$code = 'return new '.$class.'('.implode(', ', $params).');';
$function = create_function('', $code);
return $function();
}
$instance = create_instance($class, $params);
Этот метод использует create_function для инициализации класса с необходимыми параметрами. Это решение сработает с указанием класса, а вот с параметрами работать не будет. Получите ошибку: 'Call to undefined method myClass::__set_state() in index.php : runtime-created '
Эта ошибка из-за того, что var_export пытаеться вызвать не существующий метод __set_state. Этот метод очевидно плохое решение.
Решение 2 : Некрасивое.
Мы можем ограничить максимально количество аргументов - 5. Код выглядит так:
function create_instance($class, $params) {
case(count($params)) {
case 0: return new $class;
case 1: return new $class($param[0]);
case 2: return new $class($param[0], $param[1]);
case 3: return new $class($param[0], $param[1], $param[2]);
// and so on ...
}
}
$instance = create_instance($class, $params);
Это решение работает, но код выглядить ужасно.Решение 3 : Хорошее.
call_user_function_array() - наш помошник во всех случаях.
function create_instance($class, $params) {
return call_user_func_array(
array(new ReflectionClass($class), 'newInstance'),
$params
);
}
Посмотрев глубже в возможности Reflection PHP найденно идеальное решение на данный момент.
function create_instance($class, $params) {
$reflection_class = new ReflectionClass($class);
return $reflection_class->newInstanceArgs($params);
}
Комментариев нет:
Отправить комментарий