PHP
PHP代碼執行過程
PHP代碼
=>
解 詞法分析器 => 語法分析器 => 編譯器(編譯成一個obcode)
釋
層
||
V
執行引擎
=> <=
中 中間代碼 => 棧 => 符號表
間
數
據
層
PHP雖然是一個腳本語言,但不是靠解釋器解釋,而是zend虛擬機屏蔽操作系統的區別。PHP代碼編譯成opcode,由zend虛擬機來執行opcode。
但是opcode,PHP腳本一結束,opcode就消失了。
opcode能否支持緩存?
PHP本身是不支持緩存的,但是apc、xcache等加速器,實現了這樣的效果
----------------------
| PHP 編譯成-> opcode |
----------------------
| zend 執行-> opcode |
----------------------
| OS層:win,linux,mac |
----------------------
C語言是強類型,PHP怎麼就弱語言呢?
源碼:
結構體:
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount_gc;
zend_uchar type; /*active type */
zend_ucahr is_ref_gc;
};
// 當我們定義一個變量時:
$a = 4;
/*
發生了什麼:
一個結構體產生了
{
union_zvalue {long 4}
type IS_LONG
refgc_count :1
is_ref_gc :0
}
PHP底層虛擬機對變量的實現。
*/
/**
type字段的值爲以下常量:
IS_NULL IS_BOOL IS_LONG IS_DOUBLE
IS_STRING IS_ARRAY IS_OBJECT IS_RESOURCE
*/
/*
IS_NULL: 沒有值
IS_BOOL: 1/0
IS_RESOURCE: 資源
*/
$b = 'hello';
/*
{
{
value 'hello'
len 5
}
}
所以strlen的速度很快,時間複雜度O(1)
*/
變量名呢
--假設是一張花名冊--
存在符號表:hash
全局:
-------
變量名|地址
-------
|a|0X1|
-------
|b|0X2|
-------
|c|0X3|
-------
a ---> 0x1 ---> 結構體 1
b ---> 0x2 ---> 結構體 2.1
c ---> 0x3 ---> 結構體 'h'
$c = 1;
$d = $c;
$c = 1
$d = $c;
---------
zvalue: 3
type: IS_IONG
refcount_gc: 1
is_ref_gc: 0
----------
$d -> $c -> 地址
----------
zvalue: 3
type: IS_IONG
refcount_gc: 2
is_ref_gc: 0
-----------
if refcount == 0
垃圾回收機制就會回收;
(僞碼)
-----------
更改值得話,
如果發現refcount_gc有多個
就會結構體分裂
// 引用賦值
$c = 1;
$d = &$c;
zvalue: 1
type: IS_LONG
refcount_gc: 2
is_ref_gc: 1 // 引用關係
--------------
修改$d
$d = 2;
--------------
zvalue: 2
type: IS_LONG
refcount_gc: 2
is_ref_gc: 1
數組是怎樣的呢?
$a = [1, 2, 3, 4];
------------------
zvalue: *ht // 存一個指針[hash] => hash表
type: IS_ARRAY
refcount_gc: 1
is_ref_gc: 0
------------------
函數
一個函數產生一個op_array,開始 執行,已入棧的環境結構體爲環境來執行,
並生成此函數的符號表,即局部變量
如果函數內部時靜態變量,意味着它和結構體無關了,它存在op_array,
op_array只生成一次。
常量
常量全局有效
對象
zend_object_value {
handle handle
handlers *handlers
}
內存分配
全 局 常 函 |
局 部 |
符 符 量 數 | zend_mm_heap
號 號 |
表 表 表 表 |
------------- |
都是哈希表 |
------------- |