# 12.3 常量
# 12.3 常量
在腳本中使用擴展的一個方便之處是,人們可以改變自己定義的常量。你可以通過define()函數來定義一個常量。在內核中,我們將會使用REGISTER\_\*\_CONSTANT()的 家族函數來使用常量。
對于你定義的大多數常量來說,你可能希望在程序初始化的時候便定義這些變量。你可能需要在MINIT函數:
```
PHP_MINIT_FUNCTION(sample4) {
REGISTER_STRING_CONSTANT("SAMPLE4_VERSION",
PHP_SAMPLE4_EXTVER, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
```
第一個參數是你要定義的這個常量的名字。在例子中,我們定義了一個名稱為SAMPLE4*VERSION的常量。有一點很重要,這里要注意宏REGISTER**\_CONSTANT()的 使用,這些函數中為了確定常量的名稱長度使用了sizeof()。這就意味著,常量的名稱只能為文字,大家可以嘗試使用一個char* 的變量,這將導致sizeof計算出錯誤 的字符串長度。
接下來,我們來看看常量的值。在大多數情況下,它會是一個單一參數的類型,然而在STRINGL的版本中,你會看到在一些情況下會需要使用第二個參數來表明長度。 當注冊string類型的常量時,字符串的值不會被復制到常量中,而僅僅是一個引用。這意味著,動態創建的字符串需要持久化和在shutdown的階段被釋放掉。
最后,在最后一個參數,你可以通過兩個可以標識位的按位或組合傳入。CONST\_CS標識是否大小寫敏感,一般情況下CONST\_CS標識是默認使用的。對于一些特殊的 情況,比如TRUE,FALSE,NULL等等,這個參數將被省略。
在|后的標識位中的標識符說明了該常量的作用域和生命周期。當我們在MINIT中定義常量時,你可能需要在多個請求中使用這個常量,當你在RINIT中定義常量時,這個 常量會在當前請求結束的時候銷毀。
下面列出的4個創建常量常用的函數,有一個共同需要注意的地方,常量名稱一定要用文字而不是char \*類型的變量。
```
REGISTER_LONG_CONSTANT(char *name, long lval, int flags)
REGISTER_DOUBLE_CONSTANT(char *name, double dval, int flags)
REGISTER_STRING_CONSTANT(char *name, char *value, int flags)
REGISTER_STRINGL_CONSTANT(char *name,char *value, int value_len, int flags)
```
如果你沒有辦法提供文本類型的name,那么你可以嘗試使用上面4個函數的底層函數去實現相同的效果:
```
void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC)
void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC)
void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC)
void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags,int module_number TSRMLS_DC)
```
這樣就可以由傳入name\_len而擴大了該族函數的使用范圍(比如在循環中)。
module\_number是一個加載擴展或者卸載擴展時的標識。而你不需要關注它,它會自動加載到你擴展中的MINIT和RINIT中,所以在你用上面4個函數聲明常量的時候, 你可以這樣寫:
```
PHP_MINIT_FUNCTION(sample4) {
register_string_constant("SAMPLE4_VERSION",
sizeof("SAMPLE4_VERSION"),
PHP_SAMPLE4_EXTVER,
CONST_CS | CONST_PERSISTENT,
module_number TSRMLS_CC);
return SUCCESS;
}
```
除了數組和對象外,其他變量你也可以用來注冊一個常量,但是因為沒有宏和ZEND API去支持這些聲明,所以你必須手動聲明一個常量,通過下面一個例子來了解一下:
```
void php_sample4_register_boolean_constant(char *name, uint len,
zend_bool bval, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
ZVAL_BOOL(&c.value, bval);
c.flags = CONST_CS | CONST_PERSISTENT;
c.name = zend_strndup(name, len - 1);
c.name_len = len;
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
```
## links
- [目錄](preface.md)
- 12.2 [MINFO與phpinfo](12.2.html)
- 12.4 [PHP擴展中的全局變量](12.4.html)
- 介紹
- 1 PHP的生命周期
- 1.1 讓我們從SAPI開始
- 1.2 PHP的啟動與終止
- 1.3 PHP的生命周期
- 1.4 線程安全
- 1.5 PHP的生命周期
- 2 PHP變量在內核中的實現
- 2.1 變量的類型
- 2.2 變量的值
- 2.3 創建PHP變量
- 2.4 變量的存儲方式
- 2.5 變量的檢索
- 2.6 類型轉換
- 2.7 小結
- 3 內存管理
- 3.1 內存管理
- 3.2 引用計數
- 3.3 內存管理
- 4 動手編譯PHP
- 4.1 動手編譯PHP
- 4.2 動手編譯PHP
- 4.3 Unix/Linux平臺下的編譯
- 4.4 在Win32平臺上編譯PHP
- 4.5 動手編譯PHP
- 5 Your First Extension
- 5.1 Your First Extension
- 5.2 編譯我們的擴展
- 5.3 靜態編譯
- 5.4 編寫函數
- 5.5 Your First Extension
- 6 函數返回值
- 6.1 函數返回值
- 6.2 引用與函數的執行結果
- 6.3 函數返回值
- 7 函數的參數
- 7.1 函數的參數
- 7.2 函數的參數
- 7.3 函數的參數
- 8 使用HashTable與{數組}
- 8.1 使用HashTable與{數組}
- 8.2 使用HashTable與{數組}
- 8.3 使用HashTable與{數組}
- 8.4 使用HashTable與{數組}
- 9 PHP中的資源類型
- 9.1 PHP中的資源類型
- 9.2 PHP中的資源類型
- 9.3 PHP中的資源類型
- 9.4 PHP中的資源類型
- 10 PHP中的面向對象(一)
- 10.1 PHP中的面向對象(一)
- 10.2 PHP中的面向對象(一)
- 10.3 PHP中的面向對象(一)
- 10.4 PHP中的面向對象(一)
- 10.5 PHP中的面向對象(一)
- 11 PHP中的面向對象(二)
- 11.1 PHP中的面向對象(二)
- 11.2 PHP中的面向對象(二)
- 11.3 PHP中的面向對象(二)
- 12 啟動與終止的那點事
- 12.1 關于生命周期
- 12.2 MINFO與phpinfo
- 12.3 常量
- 12.4 PHP擴展中的全局變量
- 12.5 PHP語言中的超級全局變量(Superglobals)
- 12.6 小結
- 13 INI設置
- 13.1 聲明和訪問INI設置
- 13.2 小結
- 14 流式訪問
- 14.1 流的概覽
- 14.2 訪問流
- 14.3 靜態資源操作
- 14.4 links
- 15 流的實現
- 15.1 php流的表象之下
- 15.2 包裝器操作
- 15.3 實現一個包裝器
- 15.4 操縱
- 15.5 檢查
- 15.6 小結
- 16 有趣的流
- 16.1 上下文
- 16.2 過濾器
- 16.3 小結
- 17 配置和鏈接
- 17.1 autoconf
- 17.2 庫的查找
- 17.3 強制模塊依賴
- 17.4 Windows方言
- 17.5 小結
- 18 擴展生成
- 18.1 ext_skel
- 18.2 PECL_Gen
- 18.3 小結
- 19 設置宿主環境
- 19.1 嵌入式SAPI
- 19.2 構建并編譯一個宿主應用
- 19.3 通過嵌入包裝重新創建cli
- 19.4 老技術新用
- 19.5 小結
- 20 高級嵌入式
- 20.1 回調到php中
- 20.2 錯誤處理
- 20.3 初始化php
- 20.4 覆寫INI_SYSTEM和INI_PERDIR選項
- 20.5 捕獲輸出
- 20.6 同時擴展和嵌入
- 20.7 小結