背景
對於任何一種語言,了解其執行模型和內存模型都是有意義的,本文中的內容不見得正確,請多批評。
執行模型
每個請求都是一個獨立的PHP進程,兩個請求之間會完全隔離,會話和Cookie是通過其他機制在多個請求之間實現數據共享,像靜態變量和全局屬性這些會在每個請求中重新初始化。
示例
1 <?php 2 static $StaticVar = 1; 3 $StaticVar++; 4 5 echo $StaticVar.'<br/>'; 6 ?>
結果
2 //無論刷新多少次請求,結果都是2。
內存模型
基本規則
以下是PHP的內存管理規則:
- 默認按值傳遞。
- 必須顯式的聲明按引用傳遞。
- 對象類型的值是對象的地址。
1 $symbol = value;
其中:symbo是符號,存放在符號表中(全局符號表或活動符號表),value是符號引用的值。
1 $symbol_ref = &$symbol;
其中:symbo_ref和symbo會l引用同一個值。
第一個小測試
代碼
1 <?php 2 $var_a = 1; 3 $var_b = $var_a; 4 $var_c = &$var_a; 5 $var_d = $var_c; 6 $var_e = &$var_c; 7 $var_e = 2; 8 9 echo "var_a:$var_a, var_b:$var_b, var_c:$var_c, var_d:$var_d, var_e:$var_e<br/>" 10 11 ?>
結果
1 var_a:2, var_b:1, var_c:2, var_d:1, var_e:2
內存變化
第一步
第二步
第三步
第四步
第五步
第六步
第二個小測試
代碼
1 <?php 2 class TestClass { 3 private $value = 1; 4 5 function setValue($value) { 6 $this->value = $value; 7 } 8 9 function getValue() { 10 return $this->value; 11 } 12 } 13 14 $var_obj = new TestClass(); 15 $var_obj_copy = $var_obj; 16 $var_obj_ref = &$var_obj; 17 18 $var_obj_ref->setValue(2); 19 20 echo $var_obj->getValue().'<br/>'; 21 echo $var_obj_copy->getValue().'<br/>'; 22 echo $var_obj_ref->getValue().'<br/>'; 23 ?>
結果
1 //輸出結果 2 3 2 4 2 5 2
內存變化
第一步
第二步
第三步
第四步
備注
真正的PHP內存不是上面那樣,但是語義上和上面描述的沒有區別,PHP為了優化內存做了一些額外的工作。
PHP為了提高內存利用效率,並不是在賦值給符號的時候立即按值拷貝的,每個值都維護了一個引用計數(被多少個符號引用了),在某些合適的時刻會自動拷貝,不過這些時刻對於開發人員是透明的,可以不用考慮。
有感興趣的朋友,可以參考這篇文章:http://www.laruence.com/2008/09/19/520.html。