Php 臭虫还是黑客$全球的
检查此代码的输出,第二行有注释和无注释。 我的结果(PHP5.3.0)。 第二行Php 臭虫还是黑客$全球的,php,arrays,global-variables,Php,Arrays,Global Variables,检查此代码的输出,第二行有注释和无注释。 我的结果(PHP5.3.0)。 第二行 $GLOBALS["items"] = array('one', 'two', 'three', 'four', 'five' ,'six', 'seven'); $alter = &$GLOBALS["items"]; // Comment this line foreach($GLOBALS["items"] as $item) { echo get_item_id(); } function g
$GLOBALS["items"] = array('one', 'two', 'three', 'four', 'five' ,'six', 'seven');
$alter = &$GLOBALS["items"]; // Comment this line
foreach($GLOBALS["items"] as $item) {
echo get_item_id();
}
function get_item_id(){
var_dump(key($GLOBALS["items"]));
}
没有第二行:
int(1) int(2) int(3) int(4) int(5) int(6) NULL
为什么会有如此奇怪的结果?这里有一个可能的解释: 我们知道,
foreach
始终:
除非数组是,否则,foreach
对指定数组的副本而不是数组本身进行操作foreach
对数组指针有一些副作用
这意味着原始数组的内部指针未更改,并且key()
将始终返回相同的值(我们在注释该行时可以看到)。事实上,如果我们进行var\u转储($GLOBALS)
,我们会得到:
int(1) int(1) int(1) int(1) int(1) int(1) int(1)
(无参考资料)
但一旦我们生成对数组的引用(使用$alter
),$GLOBALS['items']
也将成为一个引用,因为两个条目必须指向同一数组:
["items"]=>
array(7) {
[0]=>
string(3) "one"
[1]=>
string(3) "two"
[2]=>
string(5) "three"
[3]=>
string(4) "four"
[4]=>
string(4) "five"
[5]=>
string(3) "six"
[6]=>
string(5) "seven"
}
因此,foreach
循环确实会迭代原始数组,并更改内部指针,从而影响key()
总而言之:这是引用的问题,而不是
$GLOBALS
我很诚实。。我不知道。。获取$GLOBALS的指针不应该改变变量。显然$alter接管了控制权。如果在分配数组后将$alter设置为NULL,则该数组甚至无效,并在以下循环中导致错误。这可能与$GLOBALS
实际上是一个引用数组本身有关。PHP中的引用总是很时髦。@BoltClock,您可以将$GLOBALS替换为另一个数组变量,这个hack也很有效。)我不明白为什么这应该是一个“hack”。优势是什么?在我看来,这要么是一个bug,要么是一种奇怪的行为,要么是可以解释的。+1我想象有个可怜的家伙试图在foreach循环中更改这个复制数组的值。
["items"]=>
&array(7) {
[0]=>
string(3) "one"
[1]=>
string(3) "two"
[2]=>
string(5) "three"
[3]=>
string(4) "four"
[4]=>
string(4) "five"
[5]=>
string(3) "six"
[6]=>
string(5) "seven"
}
["alter"]=>
&array(7) {
[0]=>
string(3) "one"
[1]=>
string(3) "two"
[2]=>
string(5) "three"
[3]=>
string(4) "four"
[4]=>
string(4) "five"
[5]=>
string(3) "six"
[6]=>
string(5) "seven"
}