【问题标题】:PHP Pass by reference confusionPHP 通过引用传递混淆
【发布时间】:2012-07-06 19:55:39
【问题描述】:

长话短说,我的框架中有以下功能:

public function use_parameters()
{
    $parameters = func_get_args();

    $stack = debug_backtrace();

    foreach($stack[0]['args'] as $key => &$parameter)
    {
        $parameter = array_shift($this->parameter_values);
    }
}

其中 $this->parameter_values = array('value1', 'value2', 'value3', 'value4', 'value5', ...);

在以下情况下使用:

$instance->use_parameters(&$foo, &$bah);

分配:

$foo = 'value1';
$bah = 'value2';

再次调用它

$instance->use_parameters(&$something); 

会设置

$something = 'value3'

等等。

从 5.3 开始,它将返回“已弃用:调用时传递引用已被弃用”警告。为了符合 5.3 的工作方式,我删除了 & 导致:

$instance->use_parameters($foo, $bah);

不幸的是,这导致参数未设置,我正在努力想出一个解决方案。

为了它的价值,我在 Apache/2.2.16 (Debian) 上运行 PHP v5.3.3-7

任何帮助将不胜感激。

【问题讨论】:

  • 停止使用引用。继续使用导致疼痛甚至死亡。
  • 我喜欢 20 分钟没有 cmets 的方式。每个人都在键盘上试图找到一种方法来使它工作。老实说,它看起来并不好 - 我想我现在已经测试了 func_get_args()func_get_arg()debug_backtrace() 的所有可能排列,我还没有找到任何方法来获取对动态传递的变量的引用。
  • @NikiC:没必要过头了。利亚姆在问有什么替代方案/其他锻炼方式。他乐于接受建议。
  • @itachi 这不是批评之类的 :) 只是个人建议,只要你摆弄参考资料,你就会以一种或另一种方式搞砸。
  • 顺便说一句,我计划在 PHP 5.5 中改进对可变参数函数的支持。然后,您还可以使用 function use_parameters(&... $params) 之类的语法创建一个接受 by-ref 可变参数的函数。

标签: php pass-by-reference


【解决方案1】:

你不能在 PHP 中这样做,你正在滥用引用的概念。您必须明确指定引用参数,尽管使用默认值。 但是,您不想使用 NULL 作为默认值,因为这是未分配的引用变量将被设置的值。所以你需要定义一些你知道不会用作参数的常量,现在代码看起来像

    const dummy="^^missing^^";

    public function use_parameters(&$a, &$b=self::dummy, &$c=self::dummy ) {
        $a=array_shift($this->parameter_values);
        if($b!==self::dummy) $b=array_shift($this->parameter_values);
        if($c!==self::dummy) $c=array_shift($this->parameter_values);
        # add $d,$e,$f,... as required to a sensible max number
    }

请注意,因为您正确使用了引用,所以您不需要 debug_backtrace() 垃圾。

【讨论】:

  • 是的。我的片段做你想做的事吗?
  • 使用NULL 的全部意义在于它消除了未分配的引用(除非你想接受NULL 值,也就是说)。
  • @Narf,如果我们使用您的方法,您会错过重点:$obj->use_parameters($x) 只会将下一个参数分配给 $x 如果之前已为 $x 分配了一个(非空)值,即绝对不是利亚姆想要的。
  • 等等,所以......这里的任务不是将传递的变量分配给某个数组,而是反过来?
  • 是的,据我所知,OP 试图做的是我将编码为list($foo, $bah) = $instance->use_parameters(2); 或类似的东西。参数是接收框架参数的输出。我可能是错的,但我就是这么读的。
【解决方案2】:

您不能在 PHP 5 中执行此操作,或者...正如您所见,您可以这样做,但它已被弃用并引发警告。您必须具有预定义的最大函数参数数或使用数组:

public function use_parameters(&$arg1, &$arg2 = NULL, &$arg3 = NULL)
{
    // if ($arg2 !== NULL)
    // if ($arg3 !== NULL)
}

$parameters = array(0 => &$foo, 1 => &$bah);

public function use_parameters($args)
{
    // Handle the array elements
}

【讨论】:

  • 很公平 - 我希望能够动态地(并且干净地)做到这一点,但如果不可能,那就不可能了。
  • 你的意思是在 PHP 5.3 中它会引发警告
猜你喜欢
  • 2019-05-05
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 2016-05-02
相关资源
最近更新 更多