PHP的引用變量的概念及定義方式
概念:在PHP找那個引用意味着用不同的名字來訪問同一個變量的內容。
定義方式:&;使用&符號
PHP引用變量的工作原理
<?php
//定義一個變量
$a = range(0,1000);
//定義變量b,將a變量的值賦值給b
$b = $a;
//由於COW機制,所以$b並沒有開辟出新的內存空間,而是指向同一份內存
//對$a進行修改,之前$a和$b都是指向同一個內存空間,而這個時候$a發生了改變,所以這個時候會給$a重新開辟出一個新的內存空間
$a = range(0,1000);
?>
<?php
//定義一個變量
$a = range(0,1000);
//定義變量b,將a變量的值賦值給b
$b = &$a;
$a = range(0,1000);
//引用的話就不會開辟新的內存空間;
?>
/**
寫時復制(Copy-on-Write,也縮寫為COW),顧名思義,就是在寫入時才真正復制一份內存進行修改。 COW最早應用在*nix系統中對線程與內存使用的優化,后面廣泛的被使用在各種編程語言中,如C++的STL等。 在PHP內核中,COW也是主要的內存優化手段。 在前面關於變量和內存的討論中,引用計數對變量的銷毀與回收中起着至關重要的標識作用。 引用計數存在的意義,就是為了使得COW可以正常運作,從而實現對內存的優化使用。
*/
<?php // zval 變量容器 $a = range(0,3); xdebug_debug_zval('a'); $b = $a; xdebug_debug_zval('b'); $c = &$a; xdebug_debug_zval('c'); $a = range(0,3); xdebug_debug_zval('a'); xdebug_debug_zval('b'); xdebug_debug_zval('c'); /** 每個php變量存在一個叫"zval"的變量容器中。一個zval變量容器,除了包含變量的類型和值, 還包括兩個字節的額外信息。第一個是"is_ref",是個bool值,用來標識這個變量是否是屬於引用 集合(reference set)。通過這個字節,php引擎才能把普通變量和引用變量區分開來,由於php允 許用戶通過使用&來使用自定義引用,zval變量容器中還有一個內部引用計數機制,來優化內存使 用。第二個額外字節是"refcount",用以表示指向這個zval變量容器的變量(也稱符號即symbol)個 數。所有的符號存在一個符號表中,其中每個符號都有作用域(scope),那些主腳本(比如:通過 瀏覽器請求的的腳本)和每個函數或者方法也都有作用域。 */ ?>
unset:釋放給定的變量
<?php
//unset 只會取消引用,不會銷毀空間 $a = 1; $b = &$a; unset($b); var_dump($a); // 1 var_dump($b); // null ?>
<?php $a = 1; $b = &$a; unset($a); var_dump($a); // null var_dump($b); // 1 ?>
引用對象
<?php
/*
對象本身就是引用傳遞;所以他並不會開辟新的內存空間
*/
class Person
{
public $name = "初雨";
}
$p1 = new Person;
xdebug_debug_zval("p1");
$p2 = $p1;
xdebug_debug_zval("p1");
xdebug_debug_zval("p2");
$p2->name="清風";
xdebug_debug_zval("p1");
xdebug_debug_zval("p2");
$p3 = &$p1;
xdebug_debug_zval("p1");
xdebug_debug_zval("p2");
xdebug_debug_zval("p3");
unset($p3);
unset($p1);
xdebug_debug_zval("p1");
xdebug_debug_zval("p3");
?>