在未设置时创建的PHP数组/对象作为引用传递?

时间:2017-04-11 19:45:23

标签: php arrays object pass-by-reference

我有一个小函数来从数组/对象中获取元素值:

<?php
function element( $ind, &$var, $def = NULL ) {
    echo "inside: ".json_encode(isset($var) ? $var : '<unset>') . PHP_EOL;
    if (isset($var) && is_array($var)) {
        return empty($var[$ind]) ? $def : $var[$ind];
    }
    if (isset($var) && is_object($var)) {
        return empty($var->{$ind}) ? $def : $var->{$ind};
    }
    return $def;
}

echo "var before: ".json_encode(isset($myvar) ? $myvar : '<unset>') . PHP_EOL;
$value = element( 'zz', $myvar, '' );
echo "var after: ".json_encode(isset($myvar) ? $myvar : '<unset>') . PHP_EOL;
echo PHP_EOL;
echo "array before: ".json_encode(isset($myarray) ? $myarray : '<unset>') . PHP_EOL;
$value = element( 'zz', $myarray['yy'], '' );
echo "array after: ".json_encode(isset($myarray) ? $myarray : '<unset>') . PHP_EOL;
echo PHP_EOL;
echo "object before: ".json_encode(isset($myobject) ? $myobject : '<unset>') . PHP_EOL;
$value = element( 'zz', $myobject['yy'], '' );
echo "object after: ".json_encode(isset($myobject) ? $myobject : '<unset>') . PHP_EOL;

我的问题是,如果传递的$var是一个数组或一个对象但实际上没有设置,那么它会被神奇地创建,导致出现问题:

$ php z.php
var before: "<unset>"
inside: "<unset>"
var after: "<unset>"

array before: "<unset>"
inside: "<unset>"
array after: {"yy":null}

object before: "<unset>"
inside: "<unset>"
object after: {"yy":null}

知道为什么会这样,以及如何预防?

修改

好的我得到了很多“不要那样做”和“告诉别人做某事”,所以我会解释一下这种情况。我有一个超过300,000行PHP代码的代码库,它已经使用element()函数多年来从各种变量中获取值(在超过800个地方调用),现在突然出现了庄稼由于函数神奇地创建了不存在的变量,因此出现了一些问题。具体情况就是这样,有一个非常大的多维数组$member正在传递:

<?php echo json_encode(element('base_name', $member[$wizard_type], ''); ?>

目前尚不清楚$member[xxx]在任何特定情况下会有什么元素,显然在某些情况下它没有设置,在这种情况下,只使用空字符串(第3个参数)就可以了。不幸的是,这个实际上调用 $member[$wizard_type],然后由于这个原因而不能执行代码。

如果我可以删除引用并以某种方式从element()函数中抑制错误,我想这是可以的。

1 个答案:

答案 0 :(得分:2)

手册中说明了这一点: http://php.net/manual/en/language.references.whatdo.php

  

注意:   如果通过引用分配,传递或返回未定义的变量,它将被创建。

所以

  

有任何想法[...]如何预防它?

不要作为参考传递。

如何防止这种行为。您必须重构代码,以确保给出的结果符合您的预期。