深入了解php-底層機(jī)制_第1頁(yè)
深入了解php-底層機(jī)制_第2頁(yè)
深入了解php-底層機(jī)制_第3頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、深入了解 php 底層機(jī)制(-)洪定坤摘要作為一門動(dòng)態(tài)語(yǔ)言,php 是如何實(shí)現(xiàn)的,其底層機(jī)制如何,具有什么樣的特點(diǎn),本文深入淺出介紹了包括 php 設(shè)計(jì)理念、整體構(gòu)造、核心數(shù)據(jù)構(gòu)造和變量在內(nèi)的相關(guān)底層學(xué)問(wèn),對(duì)我php 程序,優(yōu)化性能等有肯定的指導(dǎo)意義。TAGPhp 底層機(jī)制 性能優(yōu)化名目 HYPERLINK l “_TOC_250013“ 1、概述1t s HYPERLINK l “_TOC_250012“ 了解它底層實(shí)現(xiàn)的目的?2 HYPERLINK l “_TOC_250011“ 2、php 的設(shè)計(jì)理念及特點(diǎn)2 HYPERLINK l “_TOC_250010“ 3、Php 的四層體系2

2、HYPERLINK l “_TOC_250009“ 4、Sapi4 HYPERLINK l “_TOC_250008“ 5、Php的執(zhí)行流程&opcode6 HYPERLINK l “_TOC_250007“ 6、HashTable- 核心數(shù)據(jù)構(gòu)造7 HYPERLINK l “_TOC_250006“ 7、Php 變量9 HYPERLINK l “_TOC_250005“ 概述9 .0 HYPERLINK l “_TOC_250004“ 整數(shù)、浮點(diǎn)數(shù)類型變量11 HYPERLINK l “_TOC_250003“ 字符串變量11 HYPERLINK l “_TOC_250002“ 數(shù)組變量12

3、 HYPERLINK l “_TOC_250001“ 資源類型變量12 HYPERLINK l “_TOC_250000“ Php 變量的作用域131、概述whatisphp?一種適用于 web c 語(yǔ)言實(shí)現(xiàn)包含大量組件的軟件框架。更狹義點(diǎn)看,可以把它認(rèn)為是一個(gè)強(qiáng)大的ui 框架。了解它底層實(shí)現(xiàn)的目的?動(dòng)態(tài)語(yǔ)言要像用好首先得了解它內(nèi)存治理、框架模型值得我們借鑒通過(guò)擴(kuò)開放發(fā)實(shí)現(xiàn)更多更強(qiáng)大的功能,優(yōu)化我們程序的性能2、php 的設(shè)計(jì)理念及特點(diǎn)多進(jìn)程模型由于 php 盤效勞造成影響,固然,隨著時(shí)代進(jìn)展,php 也早已支持多線程模型。弱類型語(yǔ)言c/c+、java、c#等語(yǔ)言不同,Php 是一門弱類型語(yǔ)言

4、:一個(gè)變量的類型并不是一開頭就確定不變,運(yùn)行中才會(huì)確定并可能發(fā)生隱式或顯式的類型轉(zhuǎn)換,這種機(jī)制的web 開發(fā)中格外便利、高效,具體會(huì)在后面php 變量中詳述。引擎(Zend)+組件(ext)的模式降低內(nèi)部耦合中間層(sapi)web server php語(yǔ)法簡(jiǎn)潔機(jī)敏,沒有太多標(biāo)準(zhǔn)導(dǎo)致風(fēng)格混雜再差的程序員也不會(huì)寫出太離譜危害全局的程序。3、Php 的四層體系Php 的核心架構(gòu)如以下圖圖 1 php從圖上可以看出,php4ZendZend 整體用純c 實(shí)現(xiàn),是php 的內(nèi)核局部,它將php詞法、語(yǔ)法解析等一系列編譯過(guò)程為可執(zhí)行 opcode如hashtablooapi的外圍功能均圍繞zendExt

5、ensions圍圍著zend 引擎,extensions內(nèi)置函數(shù)如arrayextension現(xiàn)自己的extensionphp文本解析就是extension。SapiSapi 全稱是Server Application Programming Interface,也就是效勞端應(yīng)用編程接口,sapiphp 可以和外圍交互數(shù)據(jù),這是php的一個(gè)設(shè)計(jì),通過(guò)sapi 成功的將phpphp對(duì)不同應(yīng)用進(jìn)展兼容,而應(yīng)用本身也可以針對(duì)自己的特點(diǎn)實(shí)現(xiàn)不同的處理方式。后面將在sapi上層應(yīng)用這就是我們尋常編寫的php 程序,通過(guò)不同的sapi 方式得到各種各樣的應(yīng)用模式,如webserverwebphp車的框架就

6、是phpZend發(fā)動(dòng)機(jī)ExtSapi 可以看做是大路,車可以跑在不同類型的大路上而一次php因此,我們需要:性能優(yōu)異的引擎+適宜的車輪+正確的跑道4、Sapi如前所述,sapi php 交換數(shù)據(jù)并可以依據(jù)不同應(yīng)用特點(diǎn)實(shí)現(xiàn)特定的處理方法,我們常見的一些sapi 有:apache2handlerapache webservermod_php 模式運(yùn)行時(shí)候的處理方式,也是現(xiàn)在應(yīng)用最廣泛的一種。cgiwebserver php fastcgi 今年 fastcgi+php 得到越來(lái)越多的應(yīng)用,也是異步webserver 所唯一支持的方式。關(guān)于fastcgimod_php,可以參見另外一篇文章php 性

7、能調(diào)研-mod_php vs fastcgicli命令行調(diào)用的應(yīng)用模式Sapi 的定義及主要接口函數(shù)如以下圖圖 2 Sapi這里介紹一下其中一些主要函數(shù)startup:phpcgi 模式,在startup 的時(shí)候會(huì)加載全部的extensionshutdown:phpactivate:懇求初始化dectivate:懇求完畢時(shí)收尾工作ub_write:指定數(shù)據(jù)輸出方式apache2handler 方式,由于php 作為apache 的一個(gè)soapacheap_writecgiwrite。sapi_error:錯(cuò)誤處理函數(shù)read_post:讀取postregister_server_variabl

8、es:往$_SERVER 中注冊(cè)環(huán)境變量這個(gè)一般依據(jù)不同協(xié)議標(biāo)準(zhǔn)注冊(cè)注冊(cè)的變量。5、Php 的執(zhí)行流程&opcode我們先來(lái)看看php 代碼的執(zhí)行所經(jīng)過(guò)的流程。圖 3 php 代碼的執(zhí)行過(guò)程從圖上可以看到,php 實(shí)現(xiàn)了一個(gè)典型的動(dòng)態(tài)語(yǔ)言執(zhí)行過(guò)程:拿到一段代碼后,經(jīng)過(guò)詞(opcodes)ZEND 虛擬機(jī)順次執(zhí)行這些指令完成操作。Php 本身是用c 實(shí)現(xiàn)的,因此最終調(diào)用的也都是c 的函數(shù),實(shí)際php 看做是一個(gè)c 開發(fā)的軟件。通過(guò)上面描述不難看出,php 的執(zhí)行的核心是翻譯出來(lái)的一條一條指令,也即opcodeopcodeOpcode php opcode 由兩個(gè)參數(shù)(op1,op2)理函數(shù)組成。

9、Php opcode 處理函數(shù)的挨次執(zhí)行常見的幾個(gè)處理函數(shù)ZEND_ASSIGN_SPEC_CV_CV_HANDLER : 變量安排 $a=$bZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:函數(shù)調(diào)用ZEND_CONCAT_SPEC_CV_CV_HANDLER:字符串拼接 $a.$bZEND_ADD_SPEC_CV_CONST_HANDLER: 加法運(yùn)算 $a+2ZEND_IS_EQUAL_SPEC_CV_CONST:推斷相等 $a=1 ZEND_IS_IDENTICAL_SPEC_CV_CONST:推斷相等 $a=16、HashTable- 核心數(shù)據(jù)構(gòu)造HashTabl

10、e zend php php zend 內(nèi)部,如函數(shù)符號(hào)表、全局變量等也都是基hash table來(lái)實(shí)現(xiàn)。php hash table 具有如下特點(diǎn):key-value 查詢可以當(dāng)做數(shù)組使用添加、刪除節(jié)點(diǎn)是O1簡(jiǎn)單度key 支持混合類型:同時(shí)存在關(guān)聯(lián)數(shù)組合索引數(shù)組Value支持混合類型:array (“string”,2332)foreachZend hash table hash 表散列構(gòu)造,同時(shí)通過(guò)附加一個(gè)雙向鏈表,供給了正向、反向遍歷數(shù)組的功能。其構(gòu)造如以下圖圖 4 zend hash tablehash table key-value 形式的散列構(gòu)造,也有雙向鏈表模式,使得它能夠格外便

11、利的支持快速查找和線性遍歷。散列構(gòu)造Zend 的散列構(gòu)造是典型的hash zendhash table hash 2 倍的方式擴(kuò)容并重元素位置。初始大小均為8。key-value 快速查找時(shí)候,zend nKeyLength 標(biāo)識(shí) key 的長(zhǎng)度以作快速判定。雙向鏈表Zend hash table 通過(guò)一個(gè)鏈表構(gòu)造,實(shí)現(xiàn)了元素的線性遍歷。理論上,做遍歷使用單向鏈表就夠了,之所以使用雙向鏈表,主要目的是為了快速刪除,避開遍歷。Zend hash table 是一種復(fù)合型的構(gòu)造,作為數(shù)組使用時(shí),即支持常見的關(guān)聯(lián)數(shù)組也能夠作為挨次索引數(shù)字來(lái)使用,甚至允許2 者的混合。Php 關(guān)聯(lián)數(shù)組關(guān)聯(lián)數(shù)組是典型的

12、 hash_table 應(yīng)用。一次查詢過(guò)程經(jīng)過(guò)如下幾步getKeyHashValue h; index = n & nTableMask;Bucket *p = arBucketindex;while (p) if (p-h = h) & (p-nKeyLength = nKeyLength) RETURN p-data;p=p-next;RETURN FALTURE;從代碼可以看出,這是一個(gè)常見的 hash 查詢過(guò)程并增加一些快速判定加速查找。Php 索引數(shù)組索引數(shù)組就是我們常見的數(shù)組,通過(guò)下標(biāo)訪問(wèn)。例如 $arr0Zend HashTable index 類型 key 同樣安排了 hash

13、 值和nKeyLength(0)。內(nèi)部成員變量nNextFreeElement idpush 后自動(dòng)加一。正是這種歸一化處理,php 才能夠?qū)崿F(xiàn)關(guān)聯(lián)和非關(guān)聯(lián)的混合push key php 數(shù)組中先后挨次并不是通過(guò)下標(biāo)大小來(lái)打算,push 的先后打算。例如 $arr1 = 2; $arr2 = 3;double key,Zend HashTablekey 處理7、Php 變量概述Php 是一門弱類型語(yǔ)言,本身不嚴(yán)格區(qū)分變量的類型。Php 在變量申明的時(shí)候不需要指定類型。Php 在程序運(yùn)行期間可能進(jìn)展變量類型的隱示轉(zhuǎn)換。和其他強(qiáng)類型語(yǔ)言一樣,程序中也可以進(jìn)展顯示的類型轉(zhuǎn)換。Php 變量可以分為簡(jiǎn)潔

14、類型(int、string、bool)、集合類型(array resource object)和常量(const)以上全部的變量在底層都是同一種構(gòu)造 zvalZvalZval zend 中另一個(gè)格外重要的數(shù)據(jù)構(gòu)造,用來(lái)標(biāo)識(shí)并實(shí)現(xiàn)php 變量,其數(shù)據(jù)構(gòu)造如下Zval 主要由三局部組成:1、 type:指定了變量所述的類型整數(shù)、字符串、數(shù)組等2refcount&is_ref:用來(lái)實(shí)現(xiàn)引用計(jì)數(shù)(后面具體介紹)3value:核心局部,存儲(chǔ)了變量的實(shí)際數(shù)據(jù)zvalueZvalue是用來(lái)保存一個(gè)變量的實(shí)際數(shù)據(jù)zvalue 是一個(gè)union,也由此實(shí)現(xiàn)了弱類型。Php 變量類型和其實(shí)際存儲(chǔ)對(duì)應(yīng)關(guān)系如下IS_

15、LONG- lvalueIS_DOUBLE - dvalueIS_ARRAY- ht IS_STRING - strIS_RESOURCE - lvalue引用計(jì)數(shù)Php 中的變量就是引用計(jì)數(shù)的典型應(yīng)用Zval is_ref ref_count 享同一份數(shù)據(jù)。避開頻繁拷貝帶來(lái)的大量消耗在進(jìn)展賦值操作時(shí),zend zval ref_count+unset 操作時(shí),ref_count-1ref_count0 時(shí)才會(huì)真正執(zhí)行銷毀操作zend is_ref 1寫時(shí)拷貝Php 變量通過(guò)引用計(jì)數(shù)實(shí)現(xiàn)變量共享數(shù)據(jù),那假設(shè)轉(zhuǎn)變其中一個(gè)變量值呢?當(dāng)試圖寫入一個(gè)變量時(shí),Zend zval 被多個(gè)變量共享,則為其復(fù)

16、制ref_count 1 zvalzval refcount,這個(gè)過(guò)程稱為“zval zend copy-on-write(寫時(shí)拷貝)變量就修改了全部捆綁變量。整數(shù)、浮點(diǎn)數(shù)類型變量整數(shù)、浮點(diǎn)數(shù)是 php 中的根底類型之一,也是一個(gè)簡(jiǎn)潔型變量。zvalue 中直接存儲(chǔ)對(duì)應(yīng)的值。其類型分別是long double。從zvalue c 等強(qiáng)類型語(yǔ)言不同,php int、unsigned int、long、long long 等類型的,對(duì)它來(lái)說(shuō),整數(shù)只有一種類型也就是long。由此,可以看出,php 里面,整數(shù)的取值范圍是由編譯器位數(shù)來(lái)打算而不是固定不變的。對(duì)于浮點(diǎn)數(shù),類似整數(shù),它也不區(qū)分float

17、double double 一種類型。php 中,假設(shè)整數(shù)范圍越界了怎么辦?double trick 都是由此產(chǎn)生。字符串變量php 中的根底類型和簡(jiǎn)潔型變量通過(guò) zvalue 構(gòu)造可以看出,在 php 中,字符串是由由指向?qū)嶋H數(shù)據(jù)的指針和長(zhǎng)度構(gòu)造c+string 比較類似。c 2 ,php strlen O(1)操作。在增、修改、追加字符串操作時(shí),php 都會(huì)重安排內(nèi)存生成的字符串。最終,出于安全考慮,php 在生成一個(gè)字符串時(shí)末尾仍舊會(huì)添加0常見的字符串拼接方式及速度比較4 個(gè)變量:$strA=123;$strB = 456; $intA=123;intB=456;現(xiàn)在對(duì)如下的幾種字符串拼

18、接方式做一個(gè)比較和說(shuō)明1、$res = $strA.$strB 和$res = “$strA$strB”這種狀況下,zend malloc 一塊內(nèi)存并進(jìn)展相應(yīng)處理,其速度一般2、$strA = $strA.$strB這種是速度最快的,zend strA relloc,避開重復(fù)拷貝3、$res = $intA.$intB這種速度較慢,由于需要做隱式的格式轉(zhuǎn)換,實(shí)際編寫程序中也應(yīng)當(dāng)留意盡量避開4、$strA = sprintf (“%s%s”,$strA.$strB);sprintf 在 php 中并不是一個(gè)語(yǔ)言構(gòu)造,本身對(duì)于格式識(shí)malloc。不過(guò) sprintf 的方式最具可讀性,實(shí)際中可以依

19、據(jù)具體狀況機(jī)敏選擇。數(shù)組變量如前所述,Php Zend HashTable來(lái)自然實(shí)現(xiàn)foreach 操作如何實(shí)現(xiàn)?foreach hashtable foreachfor key-value的查找Count HashTable-NumOfElements,O(1)操作對(duì)于123這樣的字符串,zend 會(huì)轉(zhuǎn)換為其整數(shù)形式。$arr123和$arr123是等價(jià)的資源類型變量這是 php 中最簡(jiǎn)單的一種變量,也是一種復(fù)合型構(gòu)造。Php 的 zval 個(gè)問(wèn)題,只需要通過(guò)一個(gè)本質(zhì)上任意的標(biāo)識(shí)符label引用指針,這種方式被稱為資源。在 zval resource,lval 作為指針來(lái)使用,直接指向資源所在的地址。Resource mysqlifsockmemcached 等都是資源。使用資源注冊(cè)對(duì)于一個(gè)自定義

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論