日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

瀏覽:131日期: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
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本aⅴ精品一区二区三区| 在线中文字幕播放| 久久九九电影| 国产传媒在线观看| 国产精品99久久免费| 国产伦精品一区二区三区在线播放| 日欧美一区二区| 日韩激情一二三区| 欧美在线黄色| 欧美极品中文字幕| 成人在线免费观看网站| 97精品中文字幕| 国产精品久久久久蜜臀 | 亚洲专区视频| 日本欧美大码aⅴ在线播放| 久久国产乱子精品免费女| 国产精品成人**免费视频| 国产日韩1区| 久久精品理论片| 欧美成人a交片免费看| 欧美粗暴jizz性欧美20| 男人的天堂久久精品| 欧美日韩午夜电影网| 国产精品99久久免费观看| 国产 日韩 欧美一区| 9色国产精品| 日韩一区免费| 老色鬼精品视频在线观看播放| 国产不卡人人| 免费日韩av片| 国产欧美精品久久| 中文字幕在线免费观看视频| av中文字幕在线观看第一页| 亚洲精品97| 日韩国产一二三区| 成午夜精品一区二区三区软件| 99视频精品全国免费| 亚洲午夜久久| 动漫av一区| 先锋亚洲精品| 欧美日韩一区二区三区四区在线观看 | 免费亚洲婷婷| 特黄特色欧美大片| 日本vs亚洲vs韩国一区三区二区| 精品国产午夜肉伦伦影院| 亚洲二区视频| 欧美一级久久| 国产一区日韩欧美| 欧美一区二区三区久久精品| 日韩精品永久网址| 在线日韩成人| 91视频久久| 麻豆久久精品| 水蜜桃久久夜色精品一区| 蜜臀av在线播放一区二区三区| 精品一区不卡| 1024精品久久久久久久久| 国产探花一区| 五月天久久网站| 另类欧美日韩国产在线| 狠狠爱成人网| 精品一区av| 亚洲欧美网站在线观看| 福利片在线一区二区| 亚洲一区二区三区四区电影| 久久久免费人体| 免费在线观看成人| 日韩在线欧美| 国产免费av一区二区三区| 五月天久久777| 日本一区二区高清不卡| 性色一区二区| 99久久九九| 韩国女主播一区二区三区| 亚洲综合中文| 亚洲二区在线| 亚洲永久av| 久久av免费看| 日本不卡高清| 免费一区二区视频| 91精品久久久久久久久久不卡| 国产精品激情电影| 亚洲精品高潮| 红桃视频国产精品| 国产精品久久久久av电视剧| 欧美精品三级在线| 亚洲精品99| 久久天堂av| 国产成人1区| 麻豆久久久久久久| 久久激情五月婷婷| 一二三区精品| 99精品视频精品精品视频| 精品久久美女| 国产精品巨作av| 91精品福利观看| 亚洲欧美在线综合| 蜜臀a∨国产成人精品| 不卡在线一区二区| 99国产精品免费视频观看| 六月婷婷综合| 欧美国产另类| 国产精品一区二区av交换| 午夜亚洲福利| 男女性色大片免费观看一区二区| 91久久中文| 不卡一区综合视频| 婷婷综合五月| 99成人在线| 国产模特精品视频久久久久| 亚洲性图久久| 激情自拍一区| 国产一区亚洲| 亚洲高清毛片| 蜜桃tv一区二区三区| 久久久久国产精品一区三寸 | 久久精品国语| 国产精品久久久久av电视剧| 综合日韩av| 日本免费久久| 亚洲成av在线| 日韩欧美午夜| 久久男女视频| 欧美精选一区二区三区| 亚洲精品电影| 亚洲我射av| 日本视频在线一区| 欧美日韩中出| 国产精品色在线网站| 国产精品22p| 国产aⅴ精品一区二区三区久久| 久久影视三级福利片| 97国产精品| 国内精品99| 亚洲欧美日韩综合国产aⅴ| 老鸭窝亚洲一区二区三区| 免费不卡在线视频| 日本电影久久久| 狂野欧美性猛交xxxx| 日韩成人精品一区| 久久精品影视| 老司机久久99久久精品播放免费| 一级成人国产| 欧美日韩一视频区二区| 久久在线91| 亚洲爱爱视频| 在线视频免费在线观看一区二区| 免费观看久久久4p| 国产精区一区二区| 亚洲伊人av| 首页欧美精品中文字幕| 91精品国产自产在线丝袜啪| 久久三级毛片| 久久国产日本精品| 蜜桃免费网站一区二区三区| 国产欧美日本| 特黄毛片在线观看| 亚洲一区二区三区高清不卡| 亚洲精选久久| 国产激情久久| 日产精品一区| 亚洲精品婷婷| 久久精品国产99| 美女网站一区| 国产日产一区| 亚洲婷婷在线| 青青草国产成人99久久| 国产成人精品一区二区三区在线| 欧美在线影院| 国产欧美成人| 欧美日韩第一| 国产亚洲字幕| 久久精品影视| 日韩激情啪啪| 日韩在线免费| 91久久精品无嫩草影院| 成人片免费看| 亚洲欧洲日韩| 伊人网在线播放| 亚洲精品日韩久久| 欧美天堂视频| 日本在线观看不卡视频| 岛国av在线播放| 亚洲人成精品久久久| a天堂资源在线| 亚欧成人精品| 久久久久久久久99精品大| 青草av.久久免费一区| 99久久婷婷| 欧美日韩一区自拍| 一区福利视频| 精品三级在线观看视频| 日韩精品一二三区| se01亚洲视频| 国产精品一级| 久久成人精品| 日韩一区电影| 国产精品久久久久久久久久妞妞 | 国内亚洲精品| 麻豆精品在线视频|