传递/返回对象+更改对象的引用不起作用

时间:2015-09-21 18:49:45

标签: php pass-by-reference

我正在使用an answer中的How to get random value out of an array来编写一个从数组中返回随机项的函数。我将其修改为pass by referencereturn a reference

不幸的是,它似乎不起作用。对返回对象的任何修改都不会持久。我做错了什么?

如果这有所不同(请不要问),我在PHP 5.4上。

function &random_value(&$array, $default=null)
{
    $k = mt_rand(0, count($array) - 1);
    $return = isset($array[$k])? $array[$k]: $default;
    return $return;
}

...用法

$companies = array();
$companies[] = array("name" => "Acme Co",  "employees"=> array( "John", "Jane" ));
$companies[] = array("name" => "Inotech",  "employees"=> array( "Bill", "Michael" ));

$x = &random_value($companies);
$x["employees"][] = "Donald";
var_dump($companies);

...输出

array(2) {
  [0] =>
  array(2) {
    'name' =>
    string(7) "Acme Co"
    'employees' =>
    array(2) {
      [0] =>
      string(4) "John"
      [1] =>
      string(4) "Jane"
    }
  }
  [1] =>
  array(2) {
    'name' =>
    string(7) "Inotech"
    'employees' =>
    array(2) {
      [0] =>
      string(4) "Bill"
      [1] =>
      string(7) "Michael"
    }
  }
}

我甚至复制并粘贴了文档中的示例,但这些示例都没有。它们都输出null

2 个答案:

答案 0 :(得分:3)

三元运算符创建一个隐式副本,它会打破引用链。使用明确的if... else

function &random_value(&$array, $default=null)
{
    $k = mt_rand(0, count($array) - 1);
    if (isset($array[$k])) {
        return $array[$k];
    } else {
        return $default;
    }
}

至于原因,docs现状:

  

注意:请注意,三元运算符是一个表达式,它不会计算变量,而是计算表达式的结果。知道是否要通过引用返回变量很重要。声明返回$ var == 42? $ a:$ b;因此,在返回引用函数中将不起作用,并在以后的PHP版本中发出警告。

另请参阅this bug三元运算符实际在foreach上下文中通过引用返回的位置,而不应该是

答案 1 :(得分:3)

我在绕着比@bishop更好的功能方面遇到了麻烦,因为我刚刚吃了一顿丰盛的午餐,但这很有效:

$x =& $companies[array_rand($companies)];
$x["employees"][] = "Donald";
var_dump($companies);