Я знаю, что можно вызвать функцию с переменным числом параметров с помощью найденного здесь 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; }
Но может ли кто-нибудь сказать мне, есть ли пример для классов с защищенными конструкторами?