Как динамически инициализировать класс РНР с динамическики параметрами. Вот решение.
Рассмотрим ситуацию когда нам нужно создать класс с параметрами. Условия храняться в 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); }
Комментариев нет:
Отправить комментарий