【问题标题】:Variable-length by-ref argument lists in functions函数中的可变长度 by-ref 参数列表
【发布时间】:2011-12-02 13:27:03
【问题描述】:

在 PHP 中你可以这样做:

function something() {
  foreach (func_get_args() as $arg)
    echo $arg;
}
something(1, 3); //echoes "13"

这对于按值传递的参数很好,但是如果我希望它们通过引用传递呢?像这样:

function something_else() {
  foreach (func_get_args() as $arg)
    $arg *= 2;
}
$a = 1;
$b = 3;
something_else($a, $b);
echo $a . $b; //should echo "26", but returns "13" when I try it

这在 PHP 中可行吗?

【问题讨论】:

标签: php pass-by-reference argument-passing variadic-functions


【解决方案1】:

您可以这样做,但它使用 PHP 5.3 中已弃用的调用时按引用传递:

function something_else() {
    $backtrace = debug_backtrace();
    foreach($backtrace[0]['args'] as &$arg)
    $arg *= 2;
}
$a = 1;
$b = 3;
something_else(&$a, &$b);
echo $a . $b;

【讨论】:

    【解决方案2】:

    没有。你不能。 ref 传递的参数的声明明确为function something(&$arg1, &$arg2)。如果编译时不知道参数个数,可以这样做:

    function something_else($args) {
          foreach ($args as $arg)
            $GLOBALS[$arg] *= 2;
    }
    $a = 1;
    $b = 3;
    something_else(array('a', 'b'));
    echo $a . $b; //returns "26"
    

    基本上,代码将函数将修改的参数名称传递给函数。 $GLOBALS 保存对脚本全局范围内所有已定义变量的引用。这意味着如果调用来自另一个函数,它将不起作用:

    function something_else($args) {
          foreach ($args as $arg)
            $GLOBALS[$arg] *= 2;
    }
    
    function other_function(){
        $a = 1;
        $b = 3;
        something_else(array('a', 'b'));
        echo $a . $b; //returns "13"
    }
    other_function();
    

    触发通知未定义的索引ab。所以另一种方法是创建一个数组,其中引用了函数将修改为的变量:

    function something_else($args) {
          foreach ($args as &$arg)
            $arg *= 2;
    }
    
    function other_fucntion(){
        $a = 1;
        $b = 3;
        something_else(array(&$a, &$b));
        echo $a . $b; //returns "26"
    }
    other_fucntion();
    

    注意foreach 行上的&。它是必需的,因此不要创建一个遍历数组的新变量。此功能需要 PHP > 5。

    【讨论】:

    • 真的不想使用 $GLOBALS,如果传递单个数组是唯一的解决方案,salathe 的答案要干净得多..
    • 完全一样的想法。我只是指出了$GLOBALS的局限性
    【解决方案3】:

    这个问题看起来很可怕,但让你幽默一下。下面是一个可怕的 hack,但您可以发送一个包含您要使用的项目的参数。

    function something_else($args) {
        foreach ($args as &$arg) {
            $arg *= 2;
        }
    }
    $a = 1;
    $b = 3;
    something_else(array(&$a, &$b));
    echo $a . $b; // 26
    

    【讨论】:

    • 嗯,这是一个想法.. 只是出于好奇,您知道这在其他语言中是否可行?
    猜你喜欢
    • 1970-01-01
    • 2011-11-27
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多