PHP中define常量的實現

來源:互聯網
上載者:User

在應用中經常使用define來定義一些常用的參數資訊,來增加程式的可讀性和可靠性。

在PHP中,常量的名字是一個簡單的標識符,執行循環中不能改變,並且預設情況下是大小寫敏感的。通常常量總是大寫的。

註:define中的第三個參數可以設定是否常量名大小寫敏感

一、常量的內部結構

typedef struct _zend_constant {    zval value; /* zval結構,PHP內部變數的儲存結構 */    int flags;  /* 常量的標記如 CONST_PERSISTENT | CONST_CS */    char *name; /* 常量名稱 */    uint name_len;  /* 常量名稱字元長度 */    int module_number;  /* 模組號 */} zend_constant;

二、PHP中定義常量

<?phpdefine('DATABASE', 'MYSQL');define('DATABASE_USER', 'ROOT');define('DATABASE_PASSWORD', 'PASSWORD');

三、分析opcode

# php -dvld.active=1 index.php
列印出opchode,如

注,查看opcode擴充VLD安裝可以閱讀 《通過VLD擴充分析PHP opcode》

這裡介紹出現的了三條指令,SEND_VAL、DO_FCALL、RETURN
SEND_VAL:傳遞參數的固定值,作業碼65
RETURN:從函數中返回結果,作業碼62
DO_FCALL:調用函數,作業碼60

更多指令說明:http://php.net/manual/en/internals2.opcodes.list.php

四、通過ZEND VM執行opcode

void zif_define(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used )ZEND_FUNCTION(define){char *name;int name_len;zval *val;zval *val_free = NULL;zend_bool non_cs = 0;//接收第三個參數,是否大小寫敏感,預設不敏感int case_sensitive = CONST_CS;zend_constant c;//PHP中常量對應的結構體變數/* * sz|b function define(string, zval [, boolean]) * 這個參數表示定義接收的參數,s為字串,z為zval,b為boolean * */if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {return;}if(non_cs) {case_sensitive = 0;}/* class constant, check if there is name and make sure class is valid & exists */if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {zend_error(E_WARNING, "Class constants cannot be defined or redefined");RETURN_FALSE;}repeat:switch (Z_TYPE_P(val)) {case IS_LONG:case IS_DOUBLE:case IS_STRING:case IS_BOOL:case IS_RESOURCE:case IS_NULL:break;//上面,允許integer, float,string 或者 boolean和 nullcase IS_OBJECT:/* 如果傳入的是對象, 通過判斷是否定義__tostring()魔術方法,重新設定val值 * 可以看出,define已經接受對象作為參數,前提條件是定義了__tostring(),並且返回的值也是integer, float,string 或者 boolean和 null * 此時,這裡的版本是php5.3.8 * */if (!val_free) {if (Z_OBJ_HT_P(val)->get) {val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);goto repeat;} else if (Z_OBJ_HT_P(val)->cast_object) {ALLOC_INIT_ZVAL(val_free);if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {val = val_free;break;}}}/* no break */default://其他類型則提示錯誤zend_error(E_WARNING,"Constants may only evaluate to scalar values");if (val_free) {zval_ptr_dtor(&val_free);}RETURN_FALSE;}c.value = *val;zval_copy_ctor(&c.value);if (val_free) {zval_ptr_dtor(&val_free);}c.flags = case_sensitive; /* non persistent */c.name = zend_strndup(name, name_len);c.name_len = name_len+1;c.module_number = PHP_USER_CONSTANT;if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {RETURN_TRUE;} else {RETURN_FALSE;}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.