php(局部/全局)变量生命周期
局部变量
局部变量的生命周期为其所在函数被调用的整个过程.当局部变量所在的函数结束时,局部变量的生命周期也随之结束.
public function test()
{
$i = 1;
}
例如在执行完test方法后,$i变量将被释放.
foreach
foreach需要注意的一点是,在循环完毕后,php并不会将释放循环中使用的变量.
$arr = array(1,2,3);
foreach($arr as $i => $v)
var_dump($i, $v);
在循环完这个数组之后,变量$i是count($arr)-1,而$v则是arr数组的最后一个值.这时$i = 2, $v = 3.
此时变量$i, $v并没有被回收
再来看一个foreach引用的例子:
$arr = array(1,2,3);
foreach($arr as $i => &$v)
var_dump($arr);
var_dump($i, $v);
我们在打印数组的时候会"惊奇"(一点也不惊奇~)的发现value前面多了一个&引用符号
实际上foreach我们可以理解成php帮我们执行了如下操作:
foreach ($arr as $i => $v)
{
$v = $arr[$i];
/*
* 你的操作
*/
$i++;
}
foreach ($arr as $i => &$v)
{
$v = &$arr[$i];
/*
* 你的操作
*/
$i++;
}
每一次循环重写了$i和$v的值,但是最后没有释放$i,$v 所以一般情况下在我们引用结束后需要 unset($v)
从上面得知foreach循环结束后,没有回收$i,$v变量...如果在这个时候,做了一些神级操作($v = $v * 2),就会“神不知鬼不觉”修改了$arr的值.
在下面的例子:
class test
{
public function citation($arr)
{
$a = 1;
foreach ($arr as $key => &$value) {
if ($key == 0) {
$a = &$value;
}
$value++;
}
return $arr;
}
}
$arr = array(1, 2, 3, 4, 5, 6, 7);
$obj = new test();
$b = $obj->citation($arr);
var_dump($b);
这个例子告诉我们,有n个&引用符号,即是当前有n个变量持有地址
再看一个引用的例子:
class test
{
public function citation($arr1)
{
foreach ($arr1 as $key => &$value) {
$value++;
}
var_dump($arr1);
}
}
$arr = array(1, 2, 3, 4, 5, 6, 7);
$obj = new test();
$obj->citation($arr);
var_dump($arr);
?>
这个例子告诉我们,php在传值的时候只是相当于传递了一个拷贝(copy),copy了一个变量传了过去. 这里有别于js
js所有变量传递都是引用
我们传递引用时可以使用如下的写法:
class test
{
public function citation(&$arr)
{
//写法1:
foreach ($arr as $key => &$value) {
$value++;
}
//写法2:
foreach ($arr as $key => $value) {
$arr[$key] = $value + 1;
}
}
}
$arr = array(1, 2, 3, 4, 5, 6, 7);
$obj = new test();
$obj->citation($arr);
var_dump($arr);
?>
全局变量
全局变量的生命周期为其所在的"php"脚本文件被调用的整个过程.当全局变量所在的脚本文件结束调用时,则全局变量的生命周期结束.
$GLOBALS
$_SERVER
$_REQUEST
$_POST
$_GET
$_FILES
$_ENV
$_COOKIE
$_SESSION
一般不建议自己定义全局变量.如何定义一个全局变量?
我们可以使用$GLOBALS定义个全局变量
$GLOBALS['z'] = 1;
静态"变量"(常量)
静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在静态存储区内分配存储单元),该 区域中的数据在整个程序的运行期间一直占用这些存储空间
(在程序整个运行期间都不释放,也可以认为是其内存地址不变,直到整个程序运行结束).
静态变量的生命周期我们一次调用结束后,该静态变量也随之消亡.这里有别于Java
java的static变量伴随着java虚拟机的退出而消亡,java虚拟机运行期间,static变量一直存在,所以java的静态变量我们可以理解成php的全局变量
我们在下面一个例子:
class classA
{
private static $s_obj = null;
public static function test()
{
$obj = self::_oGetObj();
return $obj->test();
}
private static function _oGetObj()
{
if (is_null(self::$s_obj)) {
self::$s_obj = new classB();
}
return self::$s_obj;
}
}
class classB
{
protected $_i = '';
public function __construct()
{
$i = 0;
$i++;
}
public function test()
{
var_dump($this->_i);
}
}
for($i = 0; $i < 2; $i++) {
$a = classA()->test();
}
for($i = 0; $i < 2; $i++) {
$a = new classB();
$a->test();
}
new static 和 new self 区别
写了一个例子,自己理解什么是static的后期静态绑定..听着真高端!!!