日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
PHP運(yùn)行原理和機(jī)制
雖然說 php 學(xué)起來相對(duì)簡(jiǎn)單,但是要精通也不是一件簡(jiǎn)單的事,我們除了要知道怎么使用之外,還得知道它的工作原理。

創(chuàng)新互聯(lián)建站是一家以網(wǎng)絡(luò)技術(shù)公司,為中小企業(yè)提供網(wǎng)站維護(hù)、成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站備案、服務(wù)器租用、空間域名、軟件開發(fā)、微信小程序開發(fā)等企業(yè)互聯(lián)網(wǎng)相關(guān)業(yè)務(wù),是一家有著豐富的互聯(lián)網(wǎng)運(yùn)營(yíng)推廣經(jīng)驗(yàn)的科技公司,有著多年的網(wǎng)站建站經(jīng)驗(yàn),致力于幫助中小企業(yè)在互聯(lián)網(wǎng)讓打出自已的品牌和口碑,讓企業(yè)在互聯(lián)網(wǎng)上打開一個(gè)面向全國(guó)乃至全球的業(yè)務(wù)窗口:建站歡迎來電:18980820575

PHP 是一種適用于 web 開發(fā)的腳本語言,可以將它看做是一個(gè)用C語言實(shí)現(xiàn)的包含大量組件的軟件框架。

了解 PHP 的底層實(shí)現(xiàn),有助于我們更好的運(yùn)用它,優(yōu)化我們程序的性能,從而實(shí)現(xiàn)更加強(qiáng)大的功能。

PHP 的設(shè)計(jì)理念及特點(diǎn)

PHP 被設(shè)計(jì)為一種適用于 Web 開發(fā)的動(dòng)態(tài)腳本語言,底層完全由C語言實(shí)現(xiàn),它具備以下特點(diǎn)。

  • 解釋型:程序一行一行的邊解釋邊運(yùn)行;
  • 弱類型:和 C/C++、JAVA、C# 等語言不同,PHP 是一種弱類型的語言。定義 PHP 變量時(shí)不用指明它的類型,它的類型根據(jù)賦值的數(shù)據(jù)自動(dòng)調(diào)整;另外,一個(gè)變量的類型也不是一成不變的,在運(yùn)行過程中可以給變量賦值不同類型的數(shù)據(jù),從而修改變量的類型。這種機(jī)制的靈活性在 Web 開發(fā)中非常方便和高效;
  • 多進(jìn)程模型:由于 PHP 是多進(jìn)程模型,不同請(qǐng)求間互不干涉,這樣保證了一個(gè)請(qǐng)求掛掉不會(huì)對(duì)全盤服務(wù)造成影響;當(dāng)然,隨著時(shí)代發(fā)展,PHP 也已經(jīng)支持了多線程模型;
  • 使用引擎(Zend) + 組件(ext)的模式降低內(nèi)部耦合;
  • 中間層(sapi)隔絕 web server 和 PHP。

PHP 的四層體系

PHP 的核心架構(gòu)如下圖所示:



圖1:PHP的核心架構(gòu)

從上圖可以看出,PHP 從下到上是可以分為 4 層:

1) Zend 引擎(核心)

Zend 引擎整體用C語言實(shí)現(xiàn),是 PHP 的內(nèi)核部分,它負(fù)責(zé)將 PHP 代碼翻譯(詞法、語法解析等一系列編譯過程)為可執(zhí)行的 opcode 操作碼,并實(shí)現(xiàn)相應(yīng)的處理方法、基本的數(shù)據(jù)結(jié)構(gòu)(如 hashtable、oo)、內(nèi)存分配及管理、提供相應(yīng)的 API 方法供外部調(diào)用。

Zend 是一切的核心,所有的外圍功能均圍繞 Zend 實(shí)現(xiàn)。

2) Extensions(擴(kuò)展)

圍繞著 Zend 引擎,Extensions 通過組件化的方式提供各種基礎(chǔ)服務(wù),我們常見的各種內(nèi)置函數(shù)(例如變量操作函數(shù)、字符串操作函數(shù)等)以及標(biāo)準(zhǔn)庫等都是通過 Extensions 來實(shí)現(xiàn)。

用戶也可以根據(jù)需要實(shí)現(xiàn)自己的 Extension 組件以達(dá)到功能擴(kuò)展、性能優(yōu)化等目的,這就是高手常說的“編寫 PHP 擴(kuò)展”。

3) SAPI(服務(wù)器應(yīng)用程序編程接口)

SAPI 全稱是 Server Application Programming Interface,譯為“服務(wù)器應(yīng)用程序編程接口”。

SAPI 通過一系列鉤子函數(shù),使得 PHP 可以和外圍交互數(shù)據(jù),這是 PHP 非常優(yōu)雅和成功的一個(gè)設(shè)計(jì),通過 SAPI 成功的將 PHP 本身和上層應(yīng)用解耦隔離,PHP 可以不再考慮如何針對(duì)不同應(yīng)用進(jìn)行兼容,而應(yīng)用本身也可以針對(duì)自己的特點(diǎn)實(shí)現(xiàn)不同的處理方式。

4) Application(上層應(yīng)用)

這就是我們平時(shí)編寫的 PHP 程序,通過不同的 SAPI 方式得到各種各樣的應(yīng)用模式,例如通過 Web 服務(wù)器實(shí)現(xiàn)網(wǎng)站后臺(tái)、在命令行下以腳本方式運(yùn)行等。

總結(jié)

如果將 PHP 看作一輛汽車,那么車的框架就是 PHP 本身,Zend 是車的引擎(發(fā)動(dòng)機(jī)),Ext 下面的各種組件就是車的輪子,SAPI 可以看做是公路,車可以跑在不同類型的公路上,而一次 PHP 程序的執(zhí)行就是汽車真正跑在公路上。

要想讓汽車跑得快,性能優(yōu)異的引擎+合適的車輪+正確的跑道都是缺一不可的。

PHP 常見的運(yùn)行模式

SAPI 即服務(wù)器應(yīng)用程序編程接口,是 PHP 與其他應(yīng)用交互的接口,PHP 腳本要執(zhí)行有很多方式,比如通過 Web 服務(wù)器、命令行下或者嵌入在其他程序中。

 

SAPI 提供了一個(gè)和外部通信的接口,常見的 SAPI 有:cgi、fast-cgi、cli、apache 模塊的 DLL、isapi 等。

CGI

CGI 即通用網(wǎng)關(guān)接口(Common Gateway Interface),它是一段程序,通俗的講 CGI 就象是一座橋,把網(wǎng)頁和 WEB 服務(wù)器中的執(zhí)行程序連接起來,它把 HTML 接收的指令傳遞給服務(wù)器的執(zhí)行程序,再把服務(wù)器執(zhí)行程序的結(jié)果返還給 HTML。

CGI 的跨平臺(tái)性能極佳,幾乎可以在任何操作系統(tǒng)上實(shí)現(xiàn)。

CGI 在遇到連接請(qǐng)求后,會(huì)先要?jiǎng)?chuàng)建 CGI 的子進(jìn)程,激活一個(gè) CGI 進(jìn)程,然后處理請(qǐng)求,處理完后結(jié)束這個(gè)子進(jìn)程,這就是 fork-and-execute 模式。

綜上所述,使用 CGI 方式的服務(wù)器有多少連接請(qǐng)求就會(huì)有多少 CGI 子進(jìn)程,子進(jìn)程反復(fù)加載 會(huì)導(dǎo)致 CGI 性能低下。當(dāng)用戶請(qǐng)求數(shù)量非常多時(shí),會(huì)大量擠占系統(tǒng)的資源,如內(nèi)存、CPU 時(shí)間等,造成性能低下。

FastCGI

fast-cgi 是 CGI 的升級(jí)版本,F(xiàn)astCGI 像是一個(gè)常駐(long-live)型的 CGI,它激活后可以一直執(zhí)行著。

 

FastCGI 的工作原理:

  • Web Server 啟動(dòng)時(shí)載入 FastCGI 進(jìn)程管理器(IIS ISAPI 或 Apache Module);
  • FastCGI 進(jìn)程管理器自身初始化,啟動(dòng)多個(gè) CGI 解釋器進(jìn)程(可見多個(gè) php-cgi)并等待來自 Web Server 的連接;
  • 當(dāng)客戶端請(qǐng)求到達(dá) Web Server 時(shí),F(xiàn)astCGI 進(jìn)程管理器選擇并連接到一個(gè) CGI 解釋器。Web server 將 CGI 環(huán)境變量和標(biāo)準(zhǔn)輸入發(fā)送到 FastCGI子進(jìn)程 php-cgi;
  • FastCGI 子進(jìn)程完成處理后將標(biāo)準(zhǔn)輸出和錯(cuò)誤信息從同一連接返回 Web Server。當(dāng) FastCGI 子進(jìn)程關(guān)閉連接時(shí),請(qǐng)求便處理完成了。FastCGI 子進(jìn)程接著等待并處理來自 FastCGI 進(jìn)程管理器(運(yùn)行在 Web Server 中)的下一個(gè)連接。 在 CGI 模式中,php-cgi 在此便退出了。

APACHE2HANDLER

PHP 作為 Apache 的模塊,Apache 服務(wù)器在系統(tǒng)啟動(dòng)后,預(yù)先生成多個(gè)進(jìn)程副本駐留在內(nèi)存中,一旦有請(qǐng)求出現(xiàn),就立即使用這些空余的子進(jìn)程進(jìn)行處理,這樣就不存在生成子進(jìn)程造成的延遲了。這些服務(wù)器副本在處理完一次 HTTP 請(qǐng)求之后并不立即退出,而是停留在計(jì)算機(jī)中等待下次請(qǐng)求。對(duì)于客戶瀏覽器的請(qǐng)求反應(yīng)更快,性能較高。

apache 模塊的 DLL

該運(yùn)行模式是我們以前在 windows 環(huán)境下使用 apache 服務(wù)器經(jīng)常使用的,而在模塊化(DLL)中,PHP 是與 Web 服務(wù)器一起啟動(dòng)并運(yùn)行的。(是 apache 在 CGI 的基礎(chǔ)上進(jìn)行的一種擴(kuò)展,可以加快 PHP 的運(yùn)行效率)

ISAPI

ISAPI 即 Internet Server Application Program Interface,是微軟提供的一套面向 Internet 服務(wù)的 API 接口。一個(gè) ISAPI 的 DLL,可以在被用戶請(qǐng)求激活后長(zhǎng)駐內(nèi)存,等待用戶的另一個(gè)請(qǐng)求,還可以在一個(gè) DLL 里設(shè)置多個(gè)用戶請(qǐng)求處理函數(shù),此外 ISAPI 的 DLL 應(yīng)用程序和 WWW 服務(wù)器處于同一個(gè)進(jìn)程中,效率要顯著高于 CGI。

CLI

CLI(全稱:command-line interface)命令行界面,是在圖形用戶界面得到普及之前使用最為廣泛的用戶界面,它通常不支持鼠標(biāo),用戶通過鍵盤輸入指令,計(jì)算機(jī)接收到指令后,予以執(zhí)行。也有人稱之為字符用戶界面(CUI)。

PHP 的執(zhí)行流程和 opcode

我們?cè)賮砜纯?PHP 代碼執(zhí)行所經(jīng)過的流程。



圖2:PHP 的執(zhí)行流程

 

一段PHP代碼會(huì)經(jīng)過詞法解析、語法解析等階段,會(huì)被翻譯成一個(gè)個(gè)指令(opcode),然后 zend 虛擬機(jī)會(huì)順序執(zhí)行這些指令。PHP 本身是用C語言實(shí)現(xiàn)的,因此最終調(diào)用的也是C語言的函數(shù),實(shí)際上我們可以把 PHP 看做一個(gè)C語言開發(fā)的軟件。

PHP 執(zhí)行的核心就是翻譯出來的一條一條指令,也就是 opcode,opcode 是 PHP 程序執(zhí)行的最基本單位。

在計(jì)算機(jī)科學(xué)領(lǐng)域中,操作碼(Operation Code)被用于描述機(jī)器語言指令中,指定要執(zhí)行某種操作的那部分機(jī)器碼,構(gòu)成 opcode 的指令格式和規(guī)范由處理器的指令規(guī)范指定。

一個(gè) opcode 由兩個(gè)參數(shù)(op1,op2)、返回值和處理函數(shù)組成。PHP 程序最終被翻譯為一組 opcode 處理函數(shù)的順序執(zhí)行。

下面列舉了幾個(gè)常見的處理函數(shù):

  • ZEND_ASSIGN_SPEC_CV_CV_HANDLER : 變量分配 ($a=$b);
  • ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:函數(shù)調(diào)用;
  • ZEND_CONCAT_SPEC_CV_CV_HANDLER:字符串拼接 $a.$b;
  • ZEND_ADD_SPEC_CV_CONST_HANDLER: 加法運(yùn)算 $a+2;
  • ZEND_IS_EQUAL_SPEC_CV_CONST:判斷相等 $a==1;
  • ZEND_IS_IDENTICAL_SPEC_CV_CONST:判斷相等 $a===1。

HashTable

HashTable是Zend的核心數(shù)據(jù)結(jié)構(gòu),在PHP里面幾乎并用來實(shí)現(xiàn)所有常見功能,我們知道的PHP數(shù)組即是其典型應(yīng)用,此外在zend內(nèi)部,如函數(shù)符號(hào)表、全局變量等也都是基于HashTable。

 

HashTable具有如下特點(diǎn):

  • 支持典型的key->value查詢;
  • 可以當(dāng)做數(shù)組使用;
  • 添加、刪除節(jié)點(diǎn)是O(1)復(fù)雜度;
  • key支持混合類型,同時(shí)存在關(guān)聯(lián)數(shù)組合索引數(shù)組;
  • Value支持混合類型:array("string",2332);
  • 支持線性遍歷,如 foreach。

Zval

由于PHP 是一門弱類型語言,本身不嚴(yán)格區(qū)分變量的類型。PHP 在聲明變量的時(shí)候不需要指定類型。PHP 在程序運(yùn)行期間可能進(jìn)行變量類型的隱式轉(zhuǎn)換。和其他強(qiáng)類型語言一樣,程序中也可以進(jìn)行顯式的類型轉(zhuǎn)換。Zval 是 Zend 中另一個(gè)非常重要的數(shù)據(jù)結(jié)構(gòu),用來標(biāo)識(shí)并實(shí)現(xiàn) PHP 變量。

Zval 主要由以下 3 部分組成。

  • Type:指定了變量所述的類型(整數(shù)、字符串、數(shù)組等);
  • refcount&is_ref:用來實(shí)現(xiàn)引用計(jì)數(shù);
  • value:是核心部分,存儲(chǔ)了變量的實(shí)際數(shù)據(jù)。

Zval 用來保存一個(gè)變量的實(shí)際數(shù)據(jù)。因?yàn)橐鎯?chǔ)多種類型,所以 zval 是一個(gè) union,也由此實(shí)現(xiàn)了弱類型。

引用計(jì)數(shù)在內(nèi)存回收、字符串操作等地方使用得非常廣泛。PHP 中的變量就是引用計(jì)數(shù)的典型應(yīng)用。Zval 的引用計(jì)數(shù)通過成員變量 is_ref 和 ref_count 實(shí)現(xiàn)。通過引用計(jì)數(shù),多個(gè)變量可以共享同一份數(shù)據(jù),避免頻繁復(fù)制帶來的大量消耗。

在進(jìn)行賦值操作時(shí),Zend 將變量指向相同的 Zval,同時(shí) ref_count++,在 unset 操作時(shí),對(duì)應(yīng)的 ref_count-1。只有 ref_count 為 0 時(shí)才會(huì)真正執(zhí)行銷毀操作。如果是引用賦值,Zend 就會(huì)修改 is_ref 為 1。

PHP 變量通過引用計(jì)數(shù)實(shí)現(xiàn)變量共享數(shù)據(jù),當(dāng)試圖寫入一個(gè)變量時(shí),Zend 若發(fā)現(xiàn)該變量指向的 Zval 被多個(gè)變量共享,則為其復(fù)制一份 ref_count 為 1 的 Zval,并遞減原 Zval 的 refcount,這個(gè)過程稱為“Zval分離”。可見,只有在有寫操作發(fā)生時(shí),Zend 才進(jìn)行復(fù)制操作,因此也叫 copy-on-write(寫時(shí)復(fù)制)。

對(duì)于引用型變量,其要求和非引用型相反,引用賦值的變量間必須是捆綁的,修改一個(gè)變量就修改了所有捆綁變量。


本文標(biāo)題:PHP運(yùn)行原理和機(jī)制
瀏覽路徑:http://www.dlmjj.cn/article/dhidepi.html