日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

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

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

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

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

PHP 的設計理念及特點

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

  • 解釋型:程序一行一行的邊解釋邊運行;
  • 弱類型:和 C/C++、JAVA、C# 等語言不同,PHP 是一種弱類型的語言。定義 PHP 變量時不用指明它的類型,它的類型根據(jù)賦值的數(shù)據(jù)自動調(diào)整;另外,一個變量的類型也不是一成不變的,在運行過程中可以給變量賦值不同類型的數(shù)據(jù),從而修改變量的類型。這種機制的靈活性在 Web 開發(fā)中非常方便和高效;
  • 多進程模型:由于 PHP 是多進程模型,不同請求間互不干涉,這樣保證了一個請求掛掉不會對全盤服務造成影響;當然,隨著時代發(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語言實現(xiàn),是 PHP 的內(nèi)核部分,它負責將 PHP 代碼翻譯(詞法、語法解析等一系列編譯過程)為可執(zhí)行的 opcode 操作碼,并實現(xiàn)相應的處理方法、基本的數(shù)據(jù)結(jié)構(gòu)(如 hashtable、oo)、內(nèi)存分配及管理、提供相應的 API 方法供外部調(diào)用。

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

2) Extensions(擴展)

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

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

3) SAPI(服務器應用程序編程接口)

SAPI 全稱是 Server Application Programming Interface,譯為“服務器應用程序編程接口”。

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

4) Application(上層應用)

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

總結(jié)

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

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

PHP 常見的運行模式

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

 

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

CGI

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

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

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

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

FastCGI

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

 

FastCGI 的工作原理:

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

APACHE2HANDLER

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

apache 模塊的 DLL

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

ISAPI

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

CLI

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

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

我們再來看看 PHP 代碼執(zhí)行所經(jīng)過的流程。



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

 

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

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

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

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

下面列舉了幾個常見的處理函數(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: 加法運算 $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里面幾乎并用來實現(xiàn)所有常見功能,我們知道的PHP數(shù)組即是其典型應用,此外在zend內(nèi)部,如函數(shù)符號表、全局變量等也都是基于HashTable。

 

HashTable具有如下特點:

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

Zval

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

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

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

Zval 用來保存一個變量的實際數(shù)據(jù)。因為要存儲多種類型,所以 zval 是一個 union,也由此實現(xiàn)了弱類型。

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

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

PHP 變量通過引用計數(shù)實現(xiàn)變量共享數(shù)據(jù),當試圖寫入一個變量時,Zend 若發(fā)現(xiàn)該變量指向的 Zval 被多個變量共享,則為其復制一份 ref_count 為 1 的 Zval,并遞減原 Zval 的 refcount,這個過程稱為“Zval分離”??梢姡挥性谟袑懖僮靼l(fā)生時,Zend 才進行復制操作,因此也叫 copy-on-write(寫時復制)。

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


網(wǎng)站欄目:PHP運行原理和機制
URL分享:http://www.5511xx.com/article/dhidepi.html