PHP Array/objects 在取消设置时作为引用传递?
PHP Array/objects passed as reference being created when unset?
我有一个小函数可以从 array/object:
中获取元素值
<?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}
知道为什么会发生这种情况以及如何预防吗?
编辑
好的,我得到了很多 "don't do that" 和 "tell somebody else to do something",所以我会解释更多的情况。我有超过 300,000 行 PHP 代码的代码库,多年来一直使用 element()
函数从各种变量中获取值(在 800 多个地方调用),现在所有由于函数神奇地创建了不存在的变量,突然出现了一些问题。具体的例子,有一个非常大的多维数组 $member
被这样传递:
<?php echo json_encode(element('base_name', $member[$wizard_type], ''); ?>
不清楚在任何给定情况下 $member[xxx]
会有什么元素,显然在某些情况下它没有设置,在这种情况下只使用空字符串(第三个参数)就可以了。不幸的是,这个调用实际上 sets $member[$wizard_type]
,然后代码因此而被执行,这是不应该的。
如果我可以从 element()
函数中删除引用并以某种方式抑制错误,我想那没问题。
说明书上是这样解释的:
http://php.net/manual/en/language.references.whatdo.php
Note:
If you assign, pass, or return an undefined variable by reference, it will get created.
所以
Any idea [...] how to prevent it?
请勿作为参考。
没有办法阻止这种行为。您必须重构代码以确保给出的结果符合您的预期。
我有一个小函数可以从 array/object:
中获取元素值<?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}
知道为什么会发生这种情况以及如何预防吗?
编辑
好的,我得到了很多 "don't do that" 和 "tell somebody else to do something",所以我会解释更多的情况。我有超过 300,000 行 PHP 代码的代码库,多年来一直使用 element()
函数从各种变量中获取值(在 800 多个地方调用),现在所有由于函数神奇地创建了不存在的变量,突然出现了一些问题。具体的例子,有一个非常大的多维数组 $member
被这样传递:
<?php echo json_encode(element('base_name', $member[$wizard_type], ''); ?>
不清楚在任何给定情况下 $member[xxx]
会有什么元素,显然在某些情况下它没有设置,在这种情况下只使用空字符串(第三个参数)就可以了。不幸的是,这个调用实际上 sets $member[$wizard_type]
,然后代码因此而被执行,这是不应该的。
如果我可以从 element()
函数中删除引用并以某种方式抑制错误,我想那没问题。
说明书上是这样解释的: http://php.net/manual/en/language.references.whatdo.php
Note: If you assign, pass, or return an undefined variable by reference, it will get created.
所以
Any idea [...] how to prevent it?
请勿作为参考。
没有办法阻止这种行为。您必须重构代码以确保给出的结果符合您的预期。