查看完整版本: PHP语言中global和$GLOBALS[]的分析

hnxxwyq 2008-6-3 09:24

PHP语言中global和$GLOBALS[]的分析

原来以为global和$GLOBALS除了写法不一样以为,其他都一样,可是在实际应用中发现,2者的区别还是很大的!
_%y'R L+~?V 先看下面的例子:[code]<?php Us,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 Hln(Wnuz+|[YB:l
~-e0i3o px5m
$var1 = 5;{mmyp eE.s4BBS
$var2 = $var3 = 0;O gZWStZ/WloB

(yg1x3Oi? test_global();
&a u%GcT"hF6l print $var2 ."\n";
7jQ/bN5g6p \3AE
;N-xh"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)h nec
$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 @Z V&|
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{J v#Xr [/quote]
#RZX1|N*S
,n^/gk{Z!A9Nt 也就是说上面代码中的[color=#ff0000]$var1[/color]和[color=#ff0000]$GLOBALS['var1'][/color]是指的同一变量,而不是2个不同的变量!
3XZL#^Dp
e A;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(ROT-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,n QR
1fYO`4m@N nt l5V/^ [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\ j.PW"c u9mZYo
[img]http://www.discuzsupport.net/blog/attachment/1212401400_0.jpg[/img]1ka:r\z

:NfS7z1aVj 而test_globals执行过以后,看变量的变化:
!w-COI!\$a)W ^f ^ a/o5Y&mNH r7x
[img]http://www.discuzsupport.net/blog/attachment/1212401690_0.jpg[/img]-vN h.H*O-J
|cw/u+d+u
此时,看图,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了!
S:xh kDQ!C"@PF0l 1[4XF FZ't)m g9q I
所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于:
cLN].F6s }E]&l!M (b|(f'NB
global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况,例如例子1.
QLy2D3}7f2p
yZ8d.A3@8_!a PH $GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致!Uuiu_'k4Z,K
E"w3w)Ebb S%n-sq2G&gA
分析到此结束,谢谢观看!
PrZ,O8L
O~ qz}FOd [[i] 本帖最后由 hnxxwyq 于 2008-6-3 09:25 编辑 [/i]]
页: [1]
查看完整版本: PHP语言中global和$GLOBALS[]的分析