Динамически вызывать класс с переменным числом параметров в конструкторе

Я знаю, что можно вызвать функцию с переменным числом параметров с помощью найденного здесь call_user_func_array () -> http://php.net/manual/en/function.call-user-func-array.php . То, что я хочу сделать, почти идентично, но вместо функции я хочу вызвать класс PHP с переменным числом параметров в его конструкторе.

Он будет работать примерно так, как показано ниже, но я не буду знать количество параметров, поэтому я не буду знать, как создать экземпляр класса.

<?php //The class name will be pulled dynamically from another source $myClass = '\Some\Dynamically\Generated\Class'; //The parameters will also be pulled from another source, for simplicity I //have used two parameters. There could be 0, 1, 2, N, ... parameters $myParameters = array ('dynamicparam1', 'dynamicparam2'); //The instantiated class needs to be called with 0, 1, 2, N, ... parameters //not just two parameters. $myClassInstance = new $myClass($myParameters[0], $myParameters[1]); 

Вы можете сделать следующее: ReflectionClass

 $myClass = '\Some\Dynamically\Generated\a'; $myParameters = array ('dynamicparam1', 'dynamicparam2'); $reflection = new \ReflectionClass($myClass); $myClassInstance = $reflection->newInstanceArgs($myParameters); 

Руководство по PHP: http://www.php.net/manual/en/reflectionclass.newinstanceargs.php

Редактировать:

В php 5.6 вы можете добиться этого с помощью распаковки Argument .

 $myClass = '\Some\Dynamically\Generated\a'; $myParameters = ['dynamicparam1', 'dynamicparam2']; $myClassInstance = new $myClass(...$myParameters); 

Я многому использую этот подход, когда функции args> 2, а не заканчиваются рождественским списком аргументов, которые должны быть в определенном порядке, я просто передаю ассоциативный массив. Пройдя в ассоциативном массиве, я могу проверить необходимые и необязательные аргументы и обрабатывать недостающие значения по мере необходимости. Что-то вроде:

 class MyClass { protected $requiredArg1; protected $optionalArg1; public function __construct(array $options = array()) { // Check for a necessary arg if (!isset($options['requiredArg1'])) { throw new Exception('Missing requiredArg1'); } // Now I can just localize $requiredArg1 = $options['requiredArg1']; $optionalArg1 = (isset($options['optionalArg1'])) ? $options['optionalArg1'] : null; // Now that you have localized args, do what you want $this->requiredArg1 = $requiredArg1; $this->optionalArg1 = $optionalArg1; } } // Example call $class = 'MyClass'; $array = array('requiredArg1' => 'Foo!', 'optionalArg1' => 'Bar!'); $instance = new $class($array); var_dump($instance->getRequiredArg1()); var_dump($instance->getOptionalArg1()); 

Я настоятельно рекомендую использовать ассоциативный массив, однако можно использовать 0-индексный массив. Вы должны быть предельно осторожны при построении массива и учетной записи для индексов, имеющих смысл, иначе вы передадите массив с смещенными аргументами и вредителями с вашей функцией.

Вы можете сделать это с помощью func_get_args() .

 class my_class { function __construct( $first = NULL ) { $params = func_get_args(); if( is_array( $first ) ) $params = $first; // the $params array will contain the // arguments passed to the child function foreach( $params as $p ) echo "Param: $p\n"; } } function my_function() { $instance = new my_class( func_get_args() ); } echo "you can still create my_class instances like normal:"; $instance = new my_class( "one", "two", "three" ); echo "\n\n\n"; echo "but also through my_function:"; my_function( "one", "two", "three" ); 

В принципе, вы просто передаете результат func_get_args конструктору своего класса и позволяете ему решать, будет ли он вызван с массивом аргументов из этой функции или будет ли он нормально вызван.

Этот код выводит

 you can still create my_class instances like normal: Param: one Param: two Param: three but also through my_function: Param: one Param: two Param: three 

Надеюсь, это поможет.

Я нашел здесь

Существует ли эквивалент call_user_func () для создания экземпляра нового класса?

пример:

 function createInstance($className, array $arguments = array()) { if(class_exists($className)) { return call_user_func_array(array( new ReflectionClass($className), 'newInstance'), $arguments); } return false; } 

Но может ли кто-нибудь сказать мне, есть ли пример для классов с защищенными конструкторами?