PHP“按引用分配”的奇怪之处

时间:2016-03-25 06:32:17

标签: php reference variable-assignment

我遇到了一个代码段,其中包含$a = & $b;但未测试$ b是否确实存在(if (isset($b)))。我不确定PHP是如何处理的,所以我敲了一个快速的裸测试,现在我更感兴趣了。

$a = array('a'=>'b', 'x'=>'y');

$b = array();

$b[10] = &$a['a'];
$b[11] = &$a['ppp'];

var_dump($a);
var_dump($b);
echo (isset($a['ppp']) ? "SET" :" NOT SET") . "\n";
echo (isset($b[11]) ? "SET" :" NOT SET") . "\n";

这是裸代码,但输出显示的是:

  • 仅仅$b[11] = &$a['ppp']的明确分配就足够了,var_dump($a)被报告为有3名成员而不是2,即使没有为$a['ppp']作出任何分配。据报告,$a['ppp']具有值(NULL),但也有isset()=FALSE

  • 与此同时,$b[11]显示值NULLisset()=FALSE,即使其指示对象(显然) 存在(!)

我很欣赏首先检查“问题”,但我主要是寻求更深入的了解。发生了什么事?

2 个答案:

答案 0 :(得分:0)

解释就像这个

一样简单
  

如果您通过引用分配,传递或返回未定义的变量,将创建

(强调我的)

这就是你正在做的事情;通过引用分配未定义的索引,以便创建它。

  

示例#1使用带有未定义变量的引用

<?php
function foo(&$var) { }

foo($a); // $a is "created" and assigned to null

$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)

$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?> 

<强> Example from PHP Manual

然后你有另一个问题:

  

与此同时,$ b [11]显示值NULL和isset()= FALSE,即使它的指示(显然)确实存在(!)

手册

也清楚地解释了这一点
  

isset - 确定变量是否设置且不是NULL

     如果测试已设置为NULL的变量

isset()将返回FALSE

由于它是NULLisset()返回FALSE。

答案 1 :(得分:0)

插槽必须存在才能为它添加另一个变量(这正是这里发生的事情,PHP的“引用”实际上并不像每个实际的那样“通过引用“操作是一个常规操作,复制被别名替换”,但它不必包含非空值,直到你为它分配一个(通过它的任何一个名称)。