hnxxwyq 2008-6-3 09:24
PHP语言中global和$GLOBALS[]的分析
原来以为global和$GLOBALS除了写法不一样以为,其他都一样,可是在实际应用中发现,2者的区别还是很大的!
_%y'R L+~?V
先看下面的例子:[code]<?phpUs,u3Q6T\TX
// 例子1T([&Dk6T
wg"DwN
function test_global() {
oR2{Vn1b5`iJ
global $var1, $var2;
)aso,o2y5c.dv
$var2 =& $var1;/H.W,]qG"q%A
}bW+a]Q/i%\\(NQ
S/]4lx\
function test_globals() {*S,B])N7I:n'ZrX
$GLOBALS['var3'] =& $GLOBALS['var1'];
7j;I c*o8FZm
}V
Hl n(Wnuz+|[YB:l
~-e0i3o
px5m
$var1 = 5;{mmypeE.s4BBS
$var2 = $var3 = 0;O
gZWStZ/WloB
(yg1x3Oi?
test_global();
&au%GcT"hF6l
print $var2 ."\n";
7jQ/bN5g6p\3AE
;N-x h"w,|x5AB
test_globals();
+cp@7R@.I
print $var3 ."\n";%H]`Qlm
?>[/code]执行结果为:
lU/dt%z4o
7O[H~][~4C'?\`h
[quote]
$ye5|-@G&{
0
&A7`)e9T{"z8U$C
5
*{'F}y/s
[/quote]
;VUQO Z
w
}HXuE
8S.O0U(wf|x"z
怎么会这样呢?不应该是2个5吗?怎么会出现1个0和1个5呢?
s&[.f)hn ec
$Ftj/e6e
恩,我们保留以上问题,深入分析$GLOBALS和global的原理!/lq;l{g.jT
7_%c9p3r+c
我们都知道变量其实是相应物理内存在代码中的"代号",假设我们上面声明的3个变量分配的内存如下图表示:
$k I)C,CL
[img]http://www.discuzsupport.net/blog/attachment/1212398765_0.jpg[/img]
[ EtOu
@ZV&|
7Yx;|TKpN
[quote]
_nG(VU4KT2~
引用php手册的$GLOBALS的解释:
&G$JoX#X;{
P{h#Q vip%V@
Global 变量:$GLOBALS
A)\3G
H{8~!I
注意: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。 W_Y@+^Z/z1{
3do,?5B(]|dz:?fE
由所有已定义全局变量组成的数组。变量名就是该数组的索引。
5WN.Yr*s(E_
%he:m*]#T"?'Z$n$`
这是一个“superglobal”,或者可以描述为自动全局变量。
aI3{Jv#Xr
[/quote]
#RZX1|N*S
,n^/gk{Z!A9Nt
也就是说上面代码中的[color=#ff0000]$var1[/color]和[color=#ff0000]$GLOBALS['var1'][/color]是指的同一变量,而不是2个不同的变量!
3XZ L#^Dp
eA;f7\ ~L
下面来分析global到底做了什么??Q&V
dWv:QC-W |z
M RG |.V4ZB*v7M:B
我们都知道php中的函数所产生的变量都是函数的私有变量,那么global关键字产生的变量也肯定逃不出这个规则,为什么这么说呢,看下面的代码:[code]<?php
t%V*L#^u
// 例子2
9z l*YEv/C {
function test() {
YX@Hn AiF
global $a;
)U~(T d|qz
unset($a);"}Jz.g q @6T
}
\1u:~-v(RO T-Y
$a = 1;!@8wU#?f
test();+wi#@RD
n{
print $a;
2\N+C~0?Oum
?>[/code]执行结果为:o/N"i#|'x
3R&||;\B/J
Zm$u$T"H
[quote]u.[(}V8GX ?cX
1HU3n9Ehr
T
[/quote]auG#a.p.u.u,D
1}*t@]~"L2v
为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug?
Nz)c6~e
^fbWLZO`;E$d
都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数后面加入[code]print $a;[/code]来测试!也就是说global产生了test函数外部$a的别名变量[color=#ff0000]“$a”[/color],为了和外面的$a区别,我把它成为--[color=#ff0000]test->$a[/color],那么例子1也这么命名的话,可得出下面的图:
?4so,nQR
1fYO`4m@N ntl5V/^
[img]http://www.discuzsupport.net/blog/attachment/1212400843_0.jpg[/img]
.U'E9Ef2H p r
N7tRpB[
%W7MI[*J
接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化由下图可以看出:
"R/kib&x2L