在构造函数中动态调用具有可变数量参数的Class

时间:2012-01-04 21:47:33

标签: php oop dynamic-data

我知道可以通过此处找到的call_user_func_array()来调用具有可变数量参数的函数 - > http://php.net/manual/en/function.call-user-func-array.php。我想要做的几乎是相同的,但我想在一个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]);

4 个答案:

答案 0 :(得分:43)

您可以使用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 unpacking实现此目的。

$myClass = '\Some\Dynamically\Generated\a';
$myParameters = ['dynamicparam1', 'dynamicparam2'];

$myClassInstance = new $myClass(...$myParameters); 

答案 1 :(得分:7)

当函数args为&gt;时,我实施了这种方法。 2,而不是最后得到一个必须按特定顺序的圣诞节参数列表,我只是传入一个关联数组。通过传入一个关联数组,我可以检查必要的和可选的args并根据需要处理缺失值。类似的东西:

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索引数组。在构造数组时,你必须非常小心,并考虑具有意义的索引,否则你将传入一个带有偏移args的数组,并对你的函数造成破坏。

答案 2 :(得分: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的结果传递给类的构造函数,然后让它决定是否使用该函数的参数数组调用它,或者是否正常调用它。 / p>

此代码输出

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

希望有所帮助。

答案 3 :(得分:0)

我在这里找到了

Is there a call_user_func() equivalent to create a new class instance?

示例:

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

但有人可以告诉我是否有一个带有受保护构造函数的类的示例?