9

我想将函数的参数转换为关联数组,其键等于参数变量名称,值等于参数值。

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)
}

我怎样才能做到这一点?

4

5 回答 5

12

您可以使用以下方法执行此操作compact

function myFunc($a, $b, $c) {
    $params = compact('a', 'b', 'c');
    // ...
}

或者,get_defined_vars()将为您提供该范围内定义的所有变量的关联数组,这将起作用,但我认为这也可能包括$_POST,$_GET等...

否则,您可以使用func_get_args获取传递给函数的所有参数的列表。虽然这不是关联的,因为它只是传递的数据(也就是说,没有变量名)。这还允许您在函数中拥有任意数量的参数。

或者,只需指定一个参数,即一个数组:

function myFunc($params) {

}

compact()似乎最接近你所追求的。

于 2009-09-14T02:46:24.137 回答
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)
}
于 2009-09-14T04:51:18.143 回答
4

我赞成@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;
    }
}

只需确保参数与字段的拼写完全相同。

于 2014-04-09T22:25:07.573 回答
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.

于 2018-12-12T05:19:00.710 回答
0

PHP 8+ 命名参数

class User
{
    private string $email;
    private string $password;
    public string $firstName;
    protected string $lastName;

    public function __construct(...$arguments)
    {

        setterObject($this, ...$arguments);

        var_dump('email: ' . $this->email);
        var_dump('password: ' . $this->password);
        var_dump($this->firstName);
        var_dump($this->lastName);


    }
}

new User(email:'xxxxx@email.com', password: '#@some@password@_', firstName: 'firstName', lastName: 'lastName');

function setterObject(object $obj, mixed ...$arguments)
{
    $args = get_defined_vars()['arguments'];
    //just named arguments
    if (count(array_filter(array_keys($args), 'is_string')) ===count($args) ) {
        array_map(function ($prop) use ($obj,$args ) {
            $prop->setAccessible(true);
            if(!is_null($args[$prop->getName()])) {
                $prop->setValue($obj, $args[$prop->getName()]);
            }
        }, (new ReflectionObject($obj))->getProperties());
    }else{
        throw new Exception('the object was not initialized');
    }
}
于 2021-09-01T16:42:15.710 回答