在PHP中实例化一个新的类实例时参数打包和解包

时间:2010-12-11 14:10:28

标签: php python dynamic

在Python中,您可以像这样打包和解压缩参数:

def myfunction(arg1, arg2, arg3):
    pass

mydict = dict(arg1='foo', arg2='bar', arg3='baz')

myfunction(**mydict)

mylist = ['foo', 'bar', 'baz']

myfunction(*mylist)

现在,PHP中有类似的东西吗?我有一个传递给函数的类,以及从数据库记录中提取的关联数组。我想创建一个类的实例,它接受与数组中的键命名相同的参数。可以吗?

修改

好的,所以我绝对没有正确地提出我的问题。当我既不知道类名也不知道参数数量时,我想动态地实例化一个新类。

我找到了答案:

http://php.net/manual/en/book.reflection.php

以下是解决方案:

class MyClass {
    public function __construct($var1, $var2, $var3) {
        echo "$var1\n";
        echo "$var2\n";
        echo "$var3\n";
    }
}

$reflector = new ReflectionClass('MyClass');
$args = array('var1'=>'foo', 'var2'=>'baz', 'var3'=>'bar');
$instance = $reflector->newInstanceArgs($args);

2 个答案:

答案 0 :(得分:2)

不,你不能直接这样做,你必须手动从数组中提取值并将它们传递给构造函数,或者更改它以使它接受数组作为参数。

您可以查看call_user_func_array,但我认为您不能将它与构造函数一起使用,因为您需要该对象的实例来调用其中一个方法。

答案 1 :(得分:1)

请注意,使用call_user_func_array()可以实现解包myfunc(*args)的参数列表:

$args = array("foo", "bar", "baz");

call_user_func_array("myfunc", $args);

对于对象方法,您可以使用call_user_func_array(array($obj, "__construct"), $args)。这里的缺点是__constructor因此会被调用两次,所以不应该做任何有趣的事情。否则,必须使用特定的init方法。

由于缺少命名参数,PHP中不存在等效于myfunc(**args)的参数。因此,一个常见的习惯是只传递dict /数组,并让函数处理命名为params。