我想将函数的参数转换为关联数组,其中键等于参数变量名,值等于参数值。
PHP:
function my_function($a, $b, $c) {
// <--- magic goes here to create the $params array
var_dump($params['a'] === $a); // Should result in bool(true)
var_dump($params['b'] === $b); // Should result in bool(true)
var_dump($params['c'] === $c); // Should result in bool(true)
}
我该怎么做?
答案 0 :(得分:12)
您可以使用compact
执行此操作:
function myFunc($a, $b, $c) {
$params = compact('a', 'b', 'c');
// ...
}
或者,get_defined_vars()
将为您提供该范围内定义的所有变量的关联数组,这可能有效,但我认为这可能还包括$_POST
,$_GET
等。 ..
否则,您可以使用func_get_args
获取传递给函数的所有参数的列表。这是不关联,因为它只是传递的数据(也就是说,没有变量名称)。这也允许你在函数中有任意数量的参数。
或者,只需指定一个参数,即一个数组:
function myFunc($params) {
}
compact()
似乎最接近您所追求的目标。
答案 1 :(得分:9)
get_defined_vars()就是你所需要的(你可以通过将它作为你在函数内部做的第一件事来确保这一点)。
function my_function($a, $b, $c) {
$params = get_defined_vars(); // <--- create the $params array
var_dump($params['a'] === $a); // results in bool(true)
var_dump($params['b'] === $b); // results in bool(true)
var_dump($params['c'] === $c); // results in bool(true)
}
答案 2 :(得分:2)
我赞成@ nickf的回答,但我想补充一点,compact()也是使用ctor实例化模型的好方法:
class User {
public $email;
public $password;
public $firstName;
public $lastName;
public function __construct ( $email, $password, $firstName, $lastName )
{
foreach ( compact( array_keys( (array)$this )) as $k => $v )
$this->$k = $v;
}
}
确保params与字段具有完全相同的拼写。
答案 3 :(得分:1)
已建议但未实现:您可以使用Reflection
来收集参数名称,然后将其与值关联:
function args_to_assoc_array($function, $args) {
if (false === strpos($function, '::')) {
$reflection = new ReflectionFunction($function);
} else {
$reflection = new ReflectionMethod(...explode('::', $function));
}
$assoc = [];
foreach ($reflection->getParameters() as $i => $parameter) {
$assoc[$parameter->getName()] = $args[$i];
}
return $assoc;
}
然后,您可以以相同的方式调用此方法,无论是在函数中还是在方法中:
function f($x, $y) { return args_to_assoc_array(__METHOD__, func_get_args()); }
class A {
function m($z) { return args_to_assoc_array(__METHOD__, func_get_args()); }
}
var_dump(f(7, 2), (new A)->m(4));
array(2) {
["x"]=>
int(7)
["y"]=>
int(2)
}
array(1) {
["z"]=>
int(4)
}
我还没有计时,但是我强烈怀疑这比使用compact
要慢得多。