php中变量的生命周期[未写完]

声明 深入理解PHP7之zval

从PHP7开始, 对于在zval的value字段中能保存下的值, 就不再对他们进行引用计数了, 而是在拷贝的时候直接赋值, 这样就省掉了大量的引用计数相关的操作

  • IS_LONG
  • IS_DOUBLE

当然对于那种根本没有值, 只有类型的类型, 也不需要引用计数了:

  • IS_NULL
  • IS_FALSE
  • IS_TRUE

所以我们这里用php56来作为我们的php版本

个人建议先看一下推荐的几篇文章

$a="Hello";    // $a 分配内存地址 0x00001,并赋值 Hello 。  
$b=&$a;        // $b 分配内存地址 0x00002,并将该地址指向 0x00001 。    
$b="word";     // 为 0x00001 地址赋值 word
echo $a,$b;    // 输出 word ,word

Feature 1

$a = 'this is';
$b = 'variable';
$c = 42;

这是一个很常规,很普通的变量赋值(除了变量名取得有点随意...),如果你看了上面的文章,那么这个就很简单了..那就不多说了

file

Feature 2

$a = 'this is';
$b = $a;
$c = $a;
$c = 42;
unset($b);
unset($c);

emmm.... 这个也很简答..也不多说..

file

Feature 3

function do_something($s){
    $s = 'was';
    return $s;
}
$a = 'this is';
$b = do_something($a);

file

将变量传递给函数除了每个脚本都具有的全局符号表之外,每次调用用户定义的函数都会创建一个符号表,其中函数在本地存储其变量。每次调用某个函数时,都会创建这样的符号表,并且每次函数返回时,该符号表都将被销毁。一个函数通过使用return语句返回,或者由于函数的末尾已经到达而隐式返回。

赋值过程

第一步 为变量 $a 赋值
第二步 调用do_something函数,并把$a传递给函数

我们将这个变量传递给do_something()函数,它在变量$s中被接收。在步骤2中,您可以看到它实际上与将变量分配给另一个变量相同(如我们在前一节中用$ b = $ a所做的那样),除了该变量存储在不同的符号表中 一个属于被调用的函数,并且引用计数增加了两次,而不是正常的一次。 原因是函数的堆栈还包含对变量容器的引用。

所以这里时候把$a的值赋值给$s,这时候$s存在函数的符号表中引用了一次 recount+1,同时又赋值给函数的形参 recount+1

第三步 $s重新赋值

当我们在步骤3中为变量$ s分配新值时,原始变量容器的引用数减1,并创建一个包含新变量的新变量容器。

第四步 返回结果

在第4步中,我们用return语句返回变量。返回的变量在全局符号表中获得一个条目,并且refcount值增加1.

函数结束

当函数结束时,函数的符号表将被销毁。在销毁期间,引擎将遍历符号表中的所有变量,并减少每个可变容器的refcount。当变量容器的refcount达到0时,变量容器被销毁。如您所见,由于PHP的引用计数机制,变量容器在从函数返回时不会被复制。