电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

PHP內核探索 —— 常量的實現(xiàn)

瀏覽:5日期:2022-09-16 14:31:55

常量,顧名思義是一個常態(tài)的量值。它與值只綁定一次,它的作用在于有肋于增加程序的可讀性和可靠性。 在PHP中,常量的名字是一個簡單值的標識符,在腳本執(zhí)行期間該值不能改變。 和變量一樣,常量默認為大小寫敏感,但是按照我們的習慣常量標識符總是大寫的。 常量名和其它任何 PHP 標簽遵循同樣的命名規(guī)則。合法的常量名以字母或下劃線開始,后面跟著任何字母,數(shù)字或下劃線。

在設定以后,常量的值無法更改常量名不需要開頭的美元符號 ($)作用域不影響對常量的訪問常量值只能是字符串或數(shù)字

在這一小節(jié)我們一起看下常量與我們常見的變量有啥區(qū)別,它在執(zhí)行期間的不可改變的特性是如何實現(xiàn)的以及常量的定義過程。

首先看下常量與變量的區(qū)別,常量是在變量的zval結構的基礎上添加了一額外的元素。如下所示為PHP中常量的內部結構。

常量的內部結構

typedef struct _zend_constant { zval value; /* zval結構,PHP內部變量的存儲結構,在第一小節(jié)有說明 */ int flags; /* 常量的標記如 CONST_PERSISTENT | CONST_CS */ char *name; /* 常量名稱 */ uint name_len; int module_number; /* 模塊號 */} zend_constant;

在Zend/zend_constants.h文件的33行可以看到如上所示的結構定義。 在常量的結構中,除了與變量一樣的zval結構,它還包括屬于常量的標記,常量名以及常量所在的模塊號。

在了解了常量的存儲結構后,我們來看PHP常量的定義過程。一個例子。

define(’ICULTIVATOR’, ’www.icultivator.com’);

這是一個很常規(guī)的常量定義過程,它使用了PHP的內置函數(shù)define。常量名為ICULTIVATOR,值為一個字符串,存放在zval結構中。 從這個例子出發(fā),我們看下define定義常量的過程實現(xiàn)。

define定義常量

define是PHP的內置函數(shù),在Zend/zend_builtin_functions.c文件中定義了此函數(shù)的實現(xiàn)。如下所示為部分源碼:

/* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false) Define a new constant */ZEND_FUNCTION(define){if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 'sz|b', &name,&name_len, &val, &non_cs) == FAILURE) {return;}... // 類常量定義 此處不做介紹... // 值類型判斷和處理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;}}/* }}} */

上面的代碼已經(jīng)對對象和類常量做了簡化處理, 其實現(xiàn)基本上是一個將傳遞的參數(shù)傳遞給新建的zend_constant結構,并將這個結構體注冊到常量列表中的過程。 關于大小寫敏感,函數(shù)的第三個參數(shù)表示是否大小不敏感,默認為false(大小寫敏感)。這個參數(shù)最后會賦值給zend_constant結構體的flags字段。其在函數(shù)中實現(xiàn)代碼如下:

zend_bool non_cs = 0; // 第三個參數(shù)的臨時存儲變量int case_sensitive = CONST_CS; // 是否大小寫敏感,默認為1if(non_cs) { // 輸入為真,大小寫不敏感 case_sensitive = 0;}c.flags = case_sensitive; // 賦值給結構體字段

從上面的define函數(shù)的實現(xiàn)來看,PHP對于常量的名稱在定義時其實是沒有所謂的限制。如下所示代碼:

define(’^_^’, ’smile’);if (defined(’^_^’)) { echo ’yes’;}else{ echo ’no’;}//$var = ^_^; //語法錯誤$var = constant('^_^');

通過defined函數(shù)測試表示,‘^_^’這個常量已經(jīng)定義好,這樣的常量無法直接調用, 只能使用constant語句來使用, 否則在語法解析時會顯示錯誤。 在上面的代碼中有用到一個判斷常量是否定義的函數(shù),下面我們看看這個函數(shù)是如何實現(xiàn)的。

判斷常量是否設置

和define一樣, defined的實現(xiàn)也在Zend/zend_builtin_functions.c文件, 其實現(xiàn)是一個讀取參數(shù)變量,調用 zend_get_constant_ex函數(shù)獲取常量的值來判斷常量是否存在的過程。 而zend_get_constant_ex函數(shù)不僅包括了常規(guī)的常規(guī)的常量獲取,還包括類常量的獲取, 最后是通過zend_get_constant函數(shù)獲取常量的值。在zend_get_constant函數(shù)中,基本上是通過下面的代碼來獲取常量的值。

zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c)

除此之外,只是調用這個函數(shù)之前和之后對name有一些特殊的處理。

常量的初始化

以上通過define定義的常量的模塊編號都是PHP_USER_CONSTANT,這表示是用戶定義的常量。 除此之外我們在平時使用較多的,如在顯示所有級別錯誤報告時使用的E_ALL常量就有點不同了。 這里我們以cgi模式為例說明標準常量的定義過程。 整個調用順序如下所示:

[php_cgi_startup() -> php_module_startup() -> zend_startup() -> zend_register_standard_constants()]

void zend_register_standard_constants(TSRMLS_D){ ... // 若干常量以REGISTER_MAIN_LONG_CONSTANT設置, REGISTER_MAIN_LONG_CONSTANT('E_ALL', E_ALL, CONST_PERSISTENT | CONST_CS); ...}

REGISTER_MAIN_LONG_CONSTANT宏展開是以zend_register_long_constant實現(xiàn)。 zend_register_long_constant函數(shù)將常量中值的類型,值,名稱及模塊號賦值給新的zend_constant。 并調用zend_register_constant添加到全局的常量列表中。

[php_cgi_startup() -> php_module_startup() -> zend_startup() -> zend_register_standard_constants() -> zend_register_constant]

ZEND_API void zend_register_long_constant(const char *name, uint name_len,long lval, int flags, int module_number TSRMLS_DC){ zend_constant c; c.value.type = IS_LONG; c.value.value.lval = lval; c.flags = flags; c.name = zend_strndup(name, name_len-1); c.name_len = name_len; c.module_number = module_number; zend_register_constant(&c TSRMLS_CC);}

zend_register_constant函數(shù)首先根據(jù)常量中的c->flags判斷是否區(qū)分大小寫, 如果不區(qū)分,則名字統(tǒng)一為小寫,如果包含'',也統(tǒng)一成小寫。否則為定義的名字 然后將調用下面的語句將當前常量添加到EG(zend_constants)。 EG(zend_constants)是一個HashTable(這在前面的章節(jié)中說明), 下面的代碼是將常量添加到這個HashTable中。

zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c,sizeof(zend_constant), NULL)==FAILURE)

在php_module_startup函數(shù)中,除了zend_startup函數(shù)中有注冊標準的常量, 它本身體通過宏REGISTER_MAIN_LONG_CONSTANT等注冊了一些常量,如:PHP_VERSION,PHP_OS等。

標簽: PHP
相關文章:
主站蜘蛛池模板: 查分易-成绩发送平台官网 | 斗式提升机,斗式提升机厂家-淄博宏建机械有限公司 | 硫酸亚铁-聚合硫酸铁-除氟除磷剂-复合碳源-污水处理药剂厂家—长隆科技 | 100_150_200_250_300_350_400公斤压力空气压缩机-舰艇航天配套厂家 | 上海律师咨询_上海法律在线咨询免费_找对口律师上策法网-策法网 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | 领袖户外_深度旅游、摄影旅游、小团慢旅行、驴友网 | 安徽合肥格力空调专卖店_格力中央空调_格力空调总经销公司代理-皖格制冷设备 | 健康管理师报考条件,考试时间,报名入口—首页 | 高速龙门架厂家_监控杆_多功能灯杆_信号灯杆_锂电池太阳能路灯-鑫世源照明 | 软装设计-提供软装装饰和软装配饰及软装陈设的软装设计公司 | uv固化机-丝印uv机-工业烤箱-五金蚀刻机-分拣输送机 - 保定市丰辉机械设备制造有限公司 | 北京模型公司-军事模型-工业模型制作-北京百艺模型沙盘公司 | 地图标注|微信高德百度地图标注|地图标记-做地图[ZuoMap.com] | 广东成考网-广东成人高考网| 儿童乐园|游乐场|淘气堡招商加盟|室内儿童游乐园配套设备|生产厂家|开心哈乐儿童乐园 | 优考试_免费在线考试系统_培训考试系统_题库系统_组卷答题系统_匡优考试 | 可程式恒温恒湿试验箱|恒温恒湿箱|恒温恒湿试验箱|恒温恒湿老化试验箱|高低温试验箱价格报价-广东德瑞检测设备有限公司 | 自动焊锡机_点胶机_螺丝机-锐驰机器人| 喷砂机厂家_自动除锈抛丸机价格-成都泰盛吉自动化喷砂设备 | 天津蒸汽/热水锅炉-电锅炉安装维修直销厂家-天津鑫淼暖通设备有限公司 | 【中联邦】增稠剂_增稠粉_水性增稠剂_涂料增稠剂_工业增稠剂生产厂家 | 焊接烟尘净化器__焊烟除尘设备_打磨工作台_喷漆废气治理设备 -催化燃烧设备 _天津路博蓝天环保科技有限公司 | 水冷散热器_水冷电子散热器_大功率散热器_水冷板散热器厂家-河源市恒光辉散热器有限公司 | 青州搬家公司电话_青州搬家公司哪家好「鸿喜」青州搬家 | 乳化沥青设备_改性沥青设备_沥青加温罐_德州市昊通路桥工程有限公司 | 不锈钢复合板|钛复合板|金属复合板|南钢集团安徽金元素复合材料有限公司-官网 | 胜为光纤光缆_光纤跳线_单模尾纤_光纤收发器_ODF光纤配线架厂家直销_北京睿创胜为科技有限公司 - 北京睿创胜为科技有限公司 | 环氧乙烷灭菌器_压力蒸汽灭菌器_低温等离子过氧化氢灭菌器 _低温蒸汽甲醛灭菌器_清洗工作站_医用干燥柜_灭菌耗材-环氧乙烷灭菌器_脉动真空压力蒸汽灭菌器_低温等离子灭菌设备_河南省三强医疗器械有限责任公司 | 365文案网_全网创意文案句子素材站 | 皮带输送机-大倾角皮带输送机-皮带输送机厂家-河南坤威机械 | 苏州工作服定做-工作服定制-工作服厂家网站-尺品服饰科技(苏州)有限公司 | 采暖炉_取暖炉_生物质颗粒锅炉_颗粒壁炉_厂家加盟批发_烟台蓝澳采暖设备有限公司 | 自动气象站_气象站监测设备_全自动气象站设备_雨量监测站-山东风途物联网 | 四川成都干燥设备_回转筒干燥机_脉冲除尘器_输送设备_热风炉_成都川工星科机电设备有限公司 | 水质监测站_水质在线分析仪_水质自动监测系统_多参数水质在线监测仪_水质传感器-山东万象环境科技有限公司 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 苏州防水公司_厂房屋面外墙防水_地下室卫生间防水堵漏-苏州伊诺尔防水工程有限公司 | 欧必特空气能-商用空气能热水工程,空气能热水器,超低温空气源热泵生产厂家-湖南欧必特空气能公司 | 两头忙,井下装载机,伸缩臂装载机,30装载机/铲车,50装载机/铲车厂家_价格-莱州巨浪机械有限公司 | 重庆监控_电子围栏设备安装公司_门禁停车场管理系统-劲浪科技公司 | 防火阀、排烟防火阀、电动防火阀产品生产销售商-德州凯亿空调设备有限公司 |