PHP 变量
本文最后更新于:2024年3月18日 凌晨
PHP 变量
概述
- PHP的变量是指用一个美元符号
$
作为前缀的标识符,例如:
1 2 3 4
| $name $Age $_debugging $MAXIMUM_IMPACT
|
- 变量可以存放任意类型的值,在编译或运行时没有变量的类型检查,可以用其他不同类型的值替换一个变量的值。
1 2 3
| $what = "Fred"; $what = 35; $what = array('Fred','35','wilma');
|
- 在PHP中不需要用显示的语法来声明变量,变量第一次被赋值时,变量就被创建了,换句话说,设置变量的值也有声明变量的功能,例如,下面在PHP程序中是完全合法的。
1 2 3
| $day = 60*60?*24; echo "There are $day second in a day.\n"; There are 86400 seconds in a day
|
1 2 3 4
| if($uninitialized_varablr == NULL){ Echo "Yes!"; } Yes!
|
可变变量
- 可以引用名字存放在另外一个变量里的变量的值,例如:
1 2
| $foo = 'bar'; $$foo = 'baz';
|
变量引用
- 在PHP里,引用就是如何创建变量的别名,
$black
作为变量$white
的别名,可以使用下面的方法:
- 赋值之后,
$black
的旧值丢失了,取而代之的是,$black
此时成为存放在$white
中的值的另一个名字:
1 2 3 4 5 6 7 8
| $big_long_variable_name = "PHP"; $short = & $big_long_variable_name; $big_long_variable_name = " rocks!";
print "$short is $short\n"; print "Long is $big_long_variable_name\n"; $short is PHP rocks! Long is PHP rocks!
|
- 在赋值之后,两个变量是同一个值的不同名字,销毁其中一个变量,不会影响到另一个变量的值,如:
1 2 3 4 5
| $white = "snow"; $black = & $white; unset($white); Print $black; snow
|
1 2 3 4 5
| function &ret_ref() { $var = "PHP"; return $var; } $v = &ret_ref();
|
变量作用域
- 由变量声明的位置控制的变量作用域(scope),决定程序的哪些部分可以访问变量,在PHP中由4种类型的变量作用域:局部作用域,全局作用域,静态变量和函数参数。
局部作用域
- 在一个函数中声明的变量就是那个函数的局部变量,也就是说,它只在该函数的代码中可见(包括嵌套函数定义);在函数外面是不可访问的,另外,定义在函数外的变量(称为全局变量)在函数中默认不可访问,例如,下面的函数更新了一个局部变量而不是全局变量:
1 2 3 4 5 6 7
| function update_counter() { $counter++; } $counter = 10; update_counter(); echo $counter; 10
|
- 因为没有其他的声明,在函数里的
$counter
是那个函数的局部变量,函数增加局部变量$counter
的值,在子程序结束时$counter
的值被丢弃,全局变量$counter
的值依然为10
- 只有函数能提供局部作用域,和其他语言不一样的是,在PHP里不可以创建一个作用域是循环,条件分支或其他块类型的变量。
全局作用域
- 在函数外声明的变量就是全局的变量,它们可以在程序的任何部分被访问,然而,默认不能再函数中访问全局变量,要让一个函数可以访问全局变量,可以再函数中使用关键字global来声明在函数中,这里将重写
update_counter()
函数来使它可以访问全局变量$counter
1 2 3 4 5 6 7
| function update_counter() { Global $counter++; } $counter = 10; update_counter(); echo $counter; 11
|
- 另一个略显笨拙的办法是使用PHP的
$GLOBALS
数组来更新全局变量,而不是直接访问变量:
1 2 3 4 5 6 7
| function update_counter() { $GLOBALS["counter"]++; } $counter = 10; update_counter(); echo $counter; 11
|
静态变量
- 静态变量仅在局部函数中存在,但当程序执行离开此作用域时,其值并不丢失,下一次调用函数时,上次执行得到的结果仍然得以保留,可以使用关键字static来声明一个静态变量,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13
| function update_counter() { static $counter = 0; $counter++; Echo "Static counter is now $counter\n"; } $counter = 10; update_counter(); updata_counter(); echo "Global counter is $counter\n;
Static counter is now 1 Static counter is now 2 Global counter is 10
|
函数参数
1 2 3 4 5
| function greet ($name) { echo "Hello,$name\n"; } greet("Janet"); Hello,Janet
|
- 函数参数是局部的,意味着它们只能在它们的函数内有效,$name不能在greet()函数外被访问。
垃圾收集
- PHP使用引用计数(reference counting)和写时复制(copy-on-write)来管理内存,写时复制保证了在变量间复制值时不浪费内存,引用计数保证了不在需要时将内存交还给操作系统。
- 要理解PHP里的内存管理,首先要知道符号表(symbol table)的思想,一个变量有两部分–变量名(如$name)和变量值(如"Fred")符号表是一个将变量名映射到内存中变量值所在地址的数组。
- 当从一个变量复制值到另一个变量时,PHP没有为复制值使用更多的内存,相反,它更新了符号表来说明"这两个变量都是同一内存块的名字",所以下面的代码实际上并没有创建一个新数组:
1 2
| $worker = array("Fred",35,"Wilma"); $other = $worker;
|
- 如果后来修改了任意一个人拷贝,PHP将分配所需的内存来产生复制:\
- 通过延迟分配和复制,PHP在很多情形下节省了时间和内存,这就是写时复制。
- 符号表指向的每一个值都有引用计数(reference counting),它的数值表示取得那块内存的途径数目,在将数组初值赋给
$worker
和将$worker
赋给$other
之后,符号表中指向数组条目($worker
和$other
)的引用计数为2,换言之,那片内存有两种取得方式:
- 通过
$worker
或$other
,但是在$worker[1]
改变后,PHP为$worker
创建了一个新的数组,并且每个数组的引用计数都只有1
- 当一个变量离开作用域时(就像一个函数参数或局部变量到达函数结尾时),它的值的引用计数减去,当一个变量在其他内存空间被赋值时,旧值的引用计数加1每对一个值的引用计数到达0时,它的内存就会被释放,这就是引用计数。
- 引用计数是管理内存的较好方式,保持变量作用域限制于函数中,通过值来传递,并让引用计数来管理内存,如果你想要主要获得更多的信息和控制权来释放变量的值,可以使用
isset()
和unset()
函数。
- 查看一个变量是否被设置甚至是空字符串,使用
isset()
:
1 2 3
| $s1 = isset($name); $name = "Fred"; $s2 = isset($name);
|
1 2
| $name = "Fred"; unset($name);
|