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

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

PHP內核探索 —— 變量的類型:PHP弱類型變量特性是如何實現?

瀏覽:62日期:2022-09-16 14:37:55

所有的編程語言都要提供一種數據的存儲與檢索機制,PHP也不例外。其它語言大都需要在使用變量之前先定義,并且它的類型也是無法再次改變的,而PHP卻允許程序猿自由的使用變量而無須提前定義,甚至可以隨時隨意的對已存在的變量轉換成其它任何PHP支持的數據類型。在程序在運行的時候,PHP還會自動的根據需求轉換變量的類型。

如果你用過PHP,肯定體驗過PHP的弱類型的變量體系。眾所周知,PHP引擎是用C寫的,而C確實一種強類型的編程語言,PHP內核中是如何用C來實現自己的這種弱類型特性的?下面談談變量的類型。

PHP在內核中是通過zval這個結構體來存儲變量的,它的定義在Zend/zend.h文件里,簡短精煉,只有四個成員組成:

struct _zval_struct {zvalue_value value;/* 變量的值 */zend_uint refcount__gc;zend_uchar type;/* 變量當前的數據類型 */zend_uchar is_ref__gc;};typedef struct _zval_struct zval;//在Zend/zend_types.h里定義的:typedef unsigned int zend_uint;typedef unsigned char zend_uchar;

zval里的refcout__gc是zend_uint類型,也就是unsinged int型,is_ref__gc和type則是unsigned char型的。保存變量值的value則是zvalue_value類型(PHP5),它是一個Union,同樣定義在了Zend/zend.h文件里:

typedef union _zvalue_value {long lval;/* long value */double dval;/* double value */struct {char *val;int len;} str;HashTable *ht;/* hash table value */zend_object_value obj;} zvalue_value;

在以上實現的基礎上,PHP語言得以實現了8種數據類型,這些數據類型在內核中的分別對應于特定的常量,它們分別是:

常量名稱:IS_NULL第一次使用的變量如果沒有初始化過,則會自動的賦予這個變量,當然我們也可以在PHP語言中通過null這個常量來給予變量null類型的值。 這個類型的值只有一個 ,就是NULL,它和0與false是不同的。IS_BOOL布爾類型的變量有兩個值,true或者false。在PHP語言中,while、if等語句會自動的把表達式的值轉成這個類型的。IS_LONGPHP語言中的整型,在內核中是通過所在操作系統的singed long數據類型來表示的。在最常見的32位操作系統中,它可以存儲從-2147483648 到 +2147483647范圍內的任一整數。有一點需要注意的是,如果PHP語言中的整型變量超出最大值或者最小值,它并不會直接溢出,而是會被內核轉換成IS_DOUBLE類型的值然后再參與計算。再者,因為使用了singed long來作為載體,所以這也就解釋了為什么PHP語言中的整型數據都是帶符號的了。

$a=2147483647;$a++;echo $a;//會正確的輸出2147483648;IS_DOUBLEPHP中的浮點數據是通過C語言中的singed double型變量來存儲的,這最終取決與所在操作系統的浮點型實現。 我們做為程序猿,應該知道計算機是無法精準的表示浮點數的,而是采用了科學計數法來保存某個精度的浮點數。用科學計數法,計算機只用8位便可以保存2.225x10^(-308)1.798x10^308之間的浮點數。用計算機來處理浮點數簡直就是一場噩夢,十進制的0.5專成二進制是0.1,0.8轉換后是0.1100110011....。但是當我們從二進制轉換回來的時候,往往會發現并不能得到0.8。我們用1除以3這個例子來解釋這個現象:1/3=0.3333333333.....,它是一個無限循環小數,但是計算機可能只能精確存儲到0.333333,當我們再乘以三時,其實計算機計算的數是0.333333*3=0.999999,而不是我們平時數學中所期盼的1.0.IS_STRINGPHP中最常用的數據類型——字符串,在內存中的存儲和C差不多,就是一塊能夠放下這個變量所有字符的內存,并且在這個變量的zval實現里會保存著指向這塊內存的指針。與C不同的是,PHP內核還同時在zval結構里保存著這個字符串的實際長度,這個設計使PHP可以在字符串中嵌入‘0’字符,也使PHP的字符串是二進制安全的,可以安全的存儲二進制數據!本著艱苦樸素的作風,內核只會為字符串申請它長度+1的內存,最后一個字節存儲的是‘0’字符,所以在不需要二進制安全操作的時候,我們可以像通常C語言的概念那樣來使用它。IS_ARRAY數組是一個非常特殊的數據類型,它唯一的功能就是包含別的變量。在C語言中,一個數組只能承載一種類型的數據,而PHP語言中的數組則靈活的多,它可以承載任意類型的數據,這一切都是HashTable的功勞,每個HashTable中的元素都有兩部分組成:索引與值,每個元素的值都是一個獨立的zval(確切的說應該是指向某個zval的指針)。IS_OBJECT和數組一樣,對象也是用來存儲復合數據的,但是與數組不同的是,對象還需要保存以下信息:方法、訪問權限、類常量以及其它的處理邏輯。相對與zend engine V1,V2中的對象實現已經被徹底修改,所以我們PHP擴展開發者如果需要自己的擴展支持面向對象的工作方式,則應該對PHP5和PHP4分別對待!IS_RESOURCE有一些數據的內容可能無法直接呈現給PHP用戶的,比如與某臺mysql服務器的鏈接,或者直接呈現出來也沒有什么意義。但用戶還需要這類數據,因此PHP中提供了一種名為Resource(資源)的數據類型。有關這個數據類型的事宜將在第九章中介紹,現在我們只要知道有這么一種數據類型就行了。

zval結構體里的type成員的值便是以上某個IS_*常量之一。內核通過檢測變量的這個成員值來知道他是什么類型的數據并做相應的后續處理。

如果要我們檢測一個變量的類型,最直接的辦法便是去讀取它的type成員的值:

void describe_zval(zval *foo){if (foo->type == IS_NULL){php_printf('這個變量的數據類型是: NULL'); } else {php_printf('這個變量的數據類型不是NULL,這種數據類型對應的數字是: %d', foo->type); }}

上述做法看起來沒有錯誤,但它是一種被強烈禁止一種做法!

PHP內核以后可能會修改變量的實現方式,所以檢測type的方法可能在以后就不能用了。為了解決這個兼容問題,zend頭文件中定義了大量的宏,供我們檢測、操作變量使用,使用這些宏不但讓我們的程序更易讀,還具有更好的兼容性。這里我們用Z_TYPE_P()宏來改寫上面那個程序。

void describe_zval(zval *foo){ if ( Z_TYPE_P(foo) == IS_NULL ) {php_printf('這個變量的數據類型是: NULL'); } else {php_printf('這個變量的數據類型不是NULL,這種數據類型對應的數字是: %d', foo->type); }}

php_printf()函數是內核對printf()函數的一層封裝,我們可以像使用printf()函數那樣使用它。

以_P一個p結尾的宏的參數大多是*zval型變量,此外獲取變量類型的宏還有兩個,分別是Z_TYPE和Z_TYPE_PP,前者的參數是zval型,而后者的參數則是**zval。這樣我們便可以猜測一下php內核是如何實現gettype這個函數了,代碼如下:

//開始定義php語言中的函數gettypePHP_FUNCTION(gettype){//這個arg間接指向就是我們傳給gettype函數的參數。是一個zval**結構//所以我們要對他使用__PP后綴的宏。zval **arg;//這個if的操作主要是讓arg指向參數~if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 'Z', &arg) == FAILURE) {return;}//調用Z_TYPE_PP宏來獲取arg指向zval的類型。//然后是一個switch結構,RETVAL_STRING宏代表這gettype函數返回的字符串類型的值switch (Z_TYPE_PP(arg)) {case IS_NULL:RETVAL_STRING('NULL', 1);break;case IS_BOOL:RETVAL_STRING('boolean', 1);break;case IS_LONG:RETVAL_STRING('integer', 1);break;case IS_DOUBLE:RETVAL_STRING('double', 1);break;case IS_STRING:RETVAL_STRING('string', 1);break;case IS_ARRAY:RETVAL_STRING('array', 1);break;case IS_OBJECT:RETVAL_STRING('object', 1);break;case IS_RESOURCE:{char *type_name;type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);if (type_name) {RETVAL_STRING('resource', 1);break;}}default:RETVAL_STRING('unknown type', 1);}}

以上三個宏的定義在Zend/zend_operators.h里,定義分別是:

#define Z_TYPE(zval) (zval).type #define Z_TYPE_P(zval_p) Z_TYPE(*zval_p) #define Z_TYPE_PP(zval_pp) Z_TYPE(**zval_pp)

標簽: PHP
相關文章:
主站蜘蛛池模板: MTK核心板|MTK开发板|MTK模块|4G核心板|4G模块|5G核心板|5G模块|安卓核心板|安卓模块|高通核心板-深圳市新移科技有限公司 | 冷藏车-东风吸污车-纯电动环卫车-污水净化车-应急特勤保障车-程力专汽厂家-程力专用汽车股份有限公司销售二十一分公司 | 通辽信息港 - 免费发布房产、招聘、求职、二手、商铺等信息 www.tlxxg.net | 太阳能发电系统-太阳能逆变器,控制器-河北沐天太阳能科技首页 | 不锈钢法兰-碳钢法兰-法兰盘生产加工厂家-[鼎捷峰]-不锈钢法兰-碳钢法兰-法兰盘生产加工厂家-[鼎捷峰] | 盐城网络公司_盐城网站优化_盐城网站建设_盐城市启晨网络科技有限公司 | 分子精馏/精馏设备生产厂家-分子蒸馏工艺实验-新诺舜尧(天津)化工设备有限公司 | 地脚螺栓_材质_标准-永年县德联地脚螺栓厂家| 焊管生产线_焊管机组_轧辊模具_焊管设备_焊管设备厂家_石家庄翔昱机械 | 民用音响-拉杆音响-家用音响-ktv专用音响-万昌科技 | 回转炉,外热式回转窑,回转窑炉-淄博圣元窑炉工程有限公司 | 蓝鹏测控平台 - 智慧车间系统 - 车间生产数据采集与分析系统 | 衢州装饰公司|装潢公司|办公楼装修|排屋装修|别墅装修-衢州佳盛装饰 | LHH药品稳定性试验箱-BPS系列恒温恒湿箱-意大利超低温冰箱-上海一恒科学仪器有限公司 | 定制/定做衬衫厂家/公司-衬衫订做/订制价格/费用-北京圣达信 | 深圳货架厂家_金丽声精品货架_广东金丽声展示设备有限公司官网 | 美国HASKEL增压泵-伊莱科elettrotec流量开关-上海方未机械设备有限公司 | TPE_TPE热塑性弹性体_TPE原料价格_TPE材料厂家-惠州市中塑王塑胶制品公司- 中塑王塑胶制品有限公司 | led全彩屏-室内|学校|展厅|p3|户外|会议室|圆柱|p2.5LED显示屏-LED显示屏价格-LED互动地砖屏_蕙宇屏科技 | LNG鹤管_内浮盘价格,上装鹤管,装车撬厂家-连云港赛威特机械 | 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | 金属波纹补偿器厂家_不锈钢膨胀节价格_非金属伸缩节定制-庆达补偿器 | 防爆电机_ybx3系列电机_河南省南洋防爆电机有限公司 | 玻璃瓶厂家_酱菜瓶厂家_饮料瓶厂家_酒瓶厂家_玻璃杯厂家_徐州东明玻璃制品有限公司 | 篮球地板厂家_舞台木地板品牌_体育运动地板厂家_凯洁地板 | 自动检重秤-动态称重机-重量分选秤-苏州金钻称重设备系统开发有限公司 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 斗式提升机,斗式提升机厂家-淄博宏建机械有限公司 | 安徽合肥格力空调专卖店_格力中央空调_格力空调总经销公司代理-皖格制冷设备 | OLChemim试剂-ABsciex耗材-广州市自力色谱科仪有限公司 | 【电子厂招聘_普工招工网_工厂招聘信息平台】-工立方打工网 | 报警器_家用防盗报警器_烟雾报警器_燃气报警器_防盗报警系统厂家-深圳市刻锐智能科技有限公司 | 亿诺千企网-企业核心产品贸易 | RTO换向阀_VOC高温阀门_加热炉切断阀_双偏心软密封蝶阀_煤气蝶阀_提升阀-湖北霍科德阀门有限公司 | 韦伯电梯有限公司| 宝宝药浴-产后药浴-药浴加盟-艾裕-专注母婴调养泡浴 | 便民信息网_家电维修,家电清洗,开锁换锁,本地家政公司 | 权威废金属|废塑料|废纸|废铜|废钢价格|再生资源回收行情报价中心-中废网 | 济南铝方通-济南铝方通价格-济南方通厂家-山东鲁方通建材有限公司 | 厌氧工作站-通用型厌氧工作站-上海胜秋科学仪器有限公司 | 垃圾压缩设备_垃圾处理设备_智能移动式垃圾压缩设备--山东明莱环保设备有限公司 |