局部变量

局部变量的生命周期为其所在函数被调用的整个过程.当局部变量所在的函数结束时,局部变量的生命周期也随之结束.

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的后期静态绑定..听着真高端!!!

发表回复

您的电子邮箱地址不会被公开。