Передача / Возвращение ссылок на объект + изменение объекта не работает

Я использую ответ от Как получить случайное значение из массива для записи функции, которая возвращает случайный элемент из массива. Я изменил его, чтобы перейти по ссылке и вернуть ссылку .

К сожалению, он не работает. Любые изменения в возвращаемом объекте не сохраняются. Что я делаю не так?

Я на 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 .

Тернарный оператор создает неявную копию, которая прерывает цепочку ссылок. Используйте явное 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; } } 

Что касается того, почему в документах указано:

Примечание. Обратите внимание, что тернарный оператор является выражением и что он не оценивает переменную, а результат выражения. Это важно знать, хотите ли вы вернуть переменную по ссылке. Оператор возвращает $ var == 42? $ a: $ b; поэтому функция возврата по ссылке не будет работать и предупреждение будет выпущено в более поздних версиях PHP.

См. Также эту ошибку, где тройной оператор фактически возвращается по ссылке в контексте foreach , когда это не должно.

У меня возникли проблемы, обертывая мою голову вокруг лучшего функционального аспекта, чем @bishop, поскольку я только что потратил огромный обед, однако это работает:

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