?
This document uses PHP Chinese website manual Release
常量是一個簡單值的標(biāo)識符(名字)。如同其名稱所暗示的,在腳本執(zhí)行期間該值不能改變。常量默認(rèn)為大小寫敏感。通常常量標(biāo)識符總是大寫的。
常量名和其它任何 PHP 標(biāo)簽遵循同樣的命名規(guī)則。合法的常量名以字母或下劃線開始,后面跟著任何字母,數(shù)字或下劃線。
PHP中的常量通過define()函數(shù)定義:
define('CONST_VAR_1', 1234);
常量的存儲
在內(nèi)核中常量存儲在EG(zend_constant)哈希表中,訪問時也是根據(jù)常量名直接到哈希表中查找,其實現(xiàn)比較簡單。
常量的數(shù)據(jù)結(jié)構(gòu):
typedef struct _zend_constant { zval value; //常量值 zend_string *name; //常量名 int flags; //常量標(biāo)識位 int module_number; //所屬擴(kuò)展、模塊 } zend_constant;
常量的幾個屬性都比較直觀,這里只介紹下flags,它的值可以是以下三個中任意組合:
#define CONST_CS (1<<0) //大小寫敏感 #define CONST_PERSISTENT (1<<1) //持久化的 #define CONST_CT_SUBST (1<<2) //允許編譯時替換
介紹下三種flag代表的含義:
CONST_CS: 大小寫敏感,默認(rèn)是開啟的,用戶通過define()定義的始終是區(qū)分大小寫的,通過擴(kuò)展定義的可以自由選擇
CONST_PERSISTENT: 持久化的,只有通過擴(kuò)展、內(nèi)核定義的才支持,這種常量不會在request結(jié)束時清理掉
CONST_CT_SUBST: 允許編譯時替換,編譯時如果發(fā)現(xiàn)有地方在讀取常量的值,那么編譯器會嘗試直接替換為常量值,而不是在執(zhí)行時再去讀取,目前這個flag只有TRUE、FALSE、NULL三個常量在使用
常量的銷毀
非持久化常量在request請求結(jié)束時銷毀,具體銷毀操作在:php_request_shutdown()->zend_deactivate()->shutdown_executor()-
>clean_non_persistent_constants()。 void clean_non_persistent_constants(void) { if (EG(full_tables_cleanup)) { zend_hash_apply(EG(zend_constants), clean_non_persistent_constant_full); } else { zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant); } }
然后從哈希表末尾開始向前遍歷EG(zend_constants),將非持久化常量刪除,直到碰到第一個持久化常量時,停止遍歷,正常情況下所有通過擴(kuò)展定義的常量一定是在PHP中通過define定義之前,當(dāng)然也并非絕對,這里只是說在所有常量均是在MINT階段定義的情況。
持久化常量是在php_module_shutdown()階段銷毀的,具體過程與上面類似。