2013-04-06 64 views
6

我想知道为什么PHP不会抱怨,当我们引用一个非现有的变量(是一个普通的变量或数组),这是只是它的方式,或者有什么我失踪? 例如,此代码为什么PHP在引用一个不存在的变量时不会抱怨?

<?php 
$t = &$r["er"]; 
var_dump($r); 
?> 

不会引发有关非现有变量的警告。

除此之外的var_dump显示此:

array(1) { ["er"]=> &NULL } 

&NULL是我没有意料到,我想我会得到一个简单的NULL

在此先感谢!

+3

引用未声明的变量会自动在该范围内定义其名称。 – mario 2013-04-06 16:07:17

+0

@MarkBaker:错了。看到我的答案和/或运行代码来说服自己。&使所有的区别。 – 2013-04-06 16:22:28

+0

谢谢马里奥,我明白了! – Melsi 2013-04-06 23:50:07

回答

5

如果PHP解释器引用var分配的内存为我服务,PHP将在散列表中创建一个null元素,并使用与您发送并引用它的键一样的键。这是通过运行下面的测试可见:

<?php 
$i = 0; 
$arr = []; 
$arrS = null; 
$v = memory_get_peak_usage(); 
for ($i = 0; $i < 150; $i++) { 
    $arrS = &$arr[rand()]; 
} 
$v = memory_get_peak_usage() - $v; 
echo $v; 

直到默认堆大小,PHP将只返回一个额外的0内存使用 - 因为它仍是分配已经“准备”数组项(PHP保留一些额外的哈希表元素为空,但为了性能目的分配)。你可以通过设置它从0到16(这是堆大小!)来看到它。当你超过16时,PHP将不得不分配额外的项目,并且将在i = 17,i = 18等...上这样做,创建空项目以便引用它们。

P.S:与人们所说的相反,这是不是抛出错误,警告或通知。回顾一个没有引用的空项目 - 会引用不存在的项目。大的巨大差异。

+0

很好的答案! +1。我没有认出'&'运算符 – hek2mgl 2013-04-06 16:18:45

+0

你在那里放了一段非常令人印象深刻的代码,$ i $ 11 $ v回声零,非常好学习堆,默认大小等。 你的答案的最后一行说这一切,我现在知道这个“&”将导致分配。 这个分配(例如:echo &$var;)出现在echo之前,这就是为什么php不会发出抱怨,因为 它回应了存在的东西(仅在前一步创建)!谢谢! – Melsi 2013-04-06 23:42:36

1

不会对不存在的变量发出警告。

这是参考文献的工作原理。 $a = &$b;如果还不存在,则创建$b,以供将来参考。这与通过引用传递的参数相同。也许这看起来很熟悉了:

preg_match($pattern, $string, $matches); 

这里的第三个参数是一个基准参数,从而$matches没有在方法调用的时候存在,但它会被创建。

那& NULL是我没有真正预料到的,我想我会得到一个普通的NULL。

你为什么不指望它呢? $r['er']是参考“到/从”$t。请注意,引用不是指针,$r['er']$t对同一个值的引用相同,不存在从一个到另一个的方向(因此最后一句中的引号)。

+0

+1这是一个很好的答案先生!特别是当你提到“preg_match”和“没有方向”时,这个关于方向的信息是我错过的东西,它已经帮助我深入了解事情。不幸的是,我可以接受一个答案,这是不可能的,我选择两个答案都比接受,我不得不做回声兰特(1,2);为了选择,希望我不会因此而受到惩罚!非常感谢你!那个“方向”的东西太好学了! – Melsi 2013-04-06 23:46:22

相关问题