【问题标题】:Force results of func_get_args() to be an associative array instead of 0-index将 func_get_args() 的结果强制为关联数组而不是 0-index
【发布时间】:2012-03-01 06:08:23
【问题描述】:

想知道是否可以进行类似func_get_args() (reference) 的调用,但不是生成一个 0 索引数组,而是生成一个关联数组,使用变量名作为键?

例如:

function foo($arg1, $arg2)
{
    var_dump(func_get_args());
}

foo('bar1', 'bar2');

// Output
array(2) {
  [0]=>
  string(4) "bar1"
  [1]=>
  string(4) "bar2"
}

// Preferred
array(2) {
  [arg1]=>
  string(4) "bar1"
  [arg2]=>
  string(4) "bar2"
}

我问的原因是,我需要验证这些作为数组传递给 RPC 函数的参数实际上是否已填充。而且似乎最好具体说明内容,而不是希望它们以正确的顺序传递:

// Now
if (array_key_exists(0, $args)) {

// Preferred
if (array_key_exists('arg1', $args)) {

在传递给 RPC 之前,我可以很容易地从传递给原始函数的 args 创建一个 assoc 数组,但我只是想知道是否有一个已经编译的函数可以为我做这件事。

谢谢。

-- 编辑--

抱歉,我忘了说我正在触摸的代码已经存在,这意味着我无法更改函数签名。

【问题讨论】:

  • PHP 没有命名参数,这就是为什么你不能这样传递它们的原因。因此,您实际上要寻找的是在每个 call_user_func_array 传递它之前订购一个关联数组?
  • @hakre:谢谢伙计,第一个链接就是我要找的(get_defined_vars())。我通读了 php 文档并找不到这个,似乎他们应该将它作为来自 func_get_args() 文档页面的链接。我很乐意结束这个问题,或者如果你想作为答案发布,那也可以。
  • @Mario:对不起,我忘了说它是现有代码,这意味着我无法更改签名。
  • @MikePurcell:添加了包含更多信息的答案,以便更好地在两者之间做出决定。

标签: php arguments


【解决方案1】:

您可以在函数的最开始使用get_defined_varsDocs,以便它只包含传递的(和定义的)参数:

function foo($arg1, $arg2)
{
    var_dump(get_defined_vars());
}

foo('bar1', 'bar2');

输出(Demo):

array(2) {
  ["arg1"]=>
  string(4) "bar1"
  ["arg2"]=>
  string(4) "bar2"
}

如果您在函数中使用静态或全局变量,请在调用get_defined_vars 之后指定它们,例如:

function foo($arg1, $arg2)
{
    $passed = get_defined_vars();

    static $staticVariable = 0;
    global $staticVariable;
    ...
}

注意这与func_get_argsDocs 不同,后者也包含传递但未定义的函数参数。此外,默认参数不是func_get_args 的一部分,但get_defined_vars 自然会将它们设置为默认值。

【讨论】:

  • 谢谢,这完全按照描述工作,并允许我针对特定的命名键和 int 键进行验证。不对这些值进行任何全局范围解析,只是将它们传递给各种函数。
【解决方案2】:

您应该要求参数本身不是参数,而是一个关联数组:

public function yourMethod(array $args = array()) {
    if (array_key_exists('foo', $args)) {
        // foo
    }

    // ...
}

$obj->yourMethod(array(
    'foo' => 'foo value',
    'bar' => 'bar value'
));

【讨论】:

  • +1 ...我可能会将if (array_key_exists('foo', $args)) 更改为性能更好的if (isset($args['foo']))
  • 只是输入了相同的答案。 +1
  • @rdlowrey:这适用于某些情况,但在其他情况下,键的存在很重要,如果值为 isset(),则 isset() 将返回 FALSE,即使密钥存在。
  • @drrcknlsn 完全同意,我想我希望 OP 能够理解 isset 的工作原理。不过,总的来说,这可能不是一个安全的假设。这是我会使用三元的那种操作:$foo = isset($args['foo']) ? $args['foo'] : NULL;,以便安全地使用更快的isset
  • 同意,这是我大部分时间都在做的事情,但是(我的错误),我忘了在 OP 中提到这已经是现有代码,这意味着我不能从 args 更改签名到一个数组。
猜你喜欢
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
相关资源
最近更新 更多