一、 解釋器部分(Zend 以引擎),負責對輸入代碼的分析、翻譯和執行;PHP 指的是咱們從外面看到的一套完整的系統。這聽起來有點糊塗,但其實並不複雜(PHP4 內部結構圖)。從功能上來分:咱們能夠分爲三部分:php
二、 功能性部分(PHP功能函數以及擴展),負責具體實現語言的各類功能(好比它的函數等等);
三、 接口部分(SAPI),負責同 WEB 服務器的會話等功能。Zend包括了第一部分的所有和第二部分的局部,PHP內核 包括了第二部分的局部和第三部分的所有。他們合起來稱之爲 PHP 包。Zend 構成了語言的核心,同時也包含了一些最基本的 PHP 預約義函數的實現。PHP 包(內核)則包含了全部創造出語言自己各類顯著特性的模塊。
(PHP 內部結構圖)java
從內容模塊上來分:咱們能夠分爲四層體系結構:python
1)Zend引擎:Zend總體用純c實現,是php的內核部分,它將php代碼翻譯(詞法、語法解析等一系列編譯過程)爲可執行opcode的處理並實現相應的處理方法、實現了基本的數據結構(如hashtable、oo)、內存分配及管理、提供了相應的api方法供外部調用,是一切的核心,全部的外圍功能均圍繞zend實現。mysql
2)Extensions擴展:圍繞着zend引擎,extensions經過組件式的方式提供各類基礎服務,咱們常見的各類內置函數(如array系列)、標準庫等都是經過extension來實現,用戶也能夠根據須要實現本身的extension以達到功能擴展、性能優化等目的(如貼吧正在使用的php中間層、富文本解析就是extension的典型應用)。c++
3)Sapi :Sapi全稱是Server Application Programming Interface,也就是服務端應用編程接口,sapi經過一系列鉤子函數,使得php能夠和外圍交互數據,這是php很是優雅和成功的一個設計,經過sapi成功的將php自己和上層應用解耦隔離,php能夠再也不考慮如何針對不一樣應用進行兼容,而應用自己也能夠針對本身的特色實現不一樣的處理方式。web
4)上層應用: 這就是咱們平時編寫的php程序,經過不一樣的sapi方式獲得各類各樣的應用模式,如經過webserver實現web應用、在命令行下以腳本方式運行等等。算法
(php結構 )sql
其架構思想:引擎(Zend)+擴展(ext)的模式:下降內部耦合apache
中間層(sapi):web server和php的通訊接口, 隔絕web server和php。編程
若是php是一輛車,那麼
車的框架就是php自己,便是咱們外面看到一套完整系統。
Zend是車的引擎(發動機)
Ext下面的各類組件就是車的輪子
Sapi能夠看作是公路,車能夠跑在不一樣類型的公路上
而一次php程序的執行就是汽車跑在公路上。
所以,咱們須要:性能優異的引擎+合適的車輪+正確的跑道
如前所述,sapi經過經過一系列的接口,使得外部應用能夠和php交換數據並能夠根據不一樣應用特色實現特定的處理方法,咱們常見的一些sapi有:
1) 、apache2handler 這是以做爲,採用模式運行時候的處理方式,也是如今應用最普遍的一種。
2)、cgi :webserverphpfastcgifastcgi+phpwebserver3)、cli :
Sapi的定義及主要接口函數:
這裏介紹一下其中一些主要函數
· startup:php被調用時初始化操做,好比cgi模式,在startup的時候會加載全部的extension並執行模塊初始化工做。
· shutdown:php關閉時收尾工做
· activate:請求初始化
· dectivate:請求結束時收尾工做
· ub_write:指定數據輸出方式,好比apache2handler方式,因爲php做爲apache的一個so存在,所以其輸出也就是調 用apache的ap_write函數,而在cgi模式下,會系統調用write。
· sapi_error:錯誤處理函數
· read_post:讀取post數據
· register_server_variables:往$_SERVER中註冊環境變量這個通常根據不一樣協議標準註冊註冊的變量。
在php源碼中,sapi實現了不少接口:以下圖:
SAPI處於PHP架構的上層,而真正的腳本執行是有Zend引擎來完成。
目前語言分爲兩類:
第一類:編譯型語言.如c/c++ Java之類,他們的共性是運行以前必須對源代碼進行編譯,而後運行編譯後的目標文件。
第二類語言:解釋型語言:如PHP,Ruby,Python。他們須要解釋器來執行這些源代碼。實際上這些語言仍是要通過編譯環節的。只不過他們在運行的時候進行編譯,爲了效率,並非每次執行的時候都會從新編譯,好比PHP的各類opcode緩存擴展(如APC Xcache等)。
說明:PHP從2000年發佈的PHP4開始就不是解釋性語言。當一個PHP腳本被執行的時候,首先PHP源代碼由Zend引擎編譯成名爲Zend opcodes的機器代碼。這些代碼保存在RAM中。而後執行opcodes運行真正的腳本。所以,PHP實際上和Java,C#等語言同樣是編譯語言。不然,它的執行會很慢。
咱們來看PHP腳本是怎麼被執行的。如hello.php:
命令行執行:php hello.php
輸出結果顯然是:Hello world!
可是執行腳本的時候,PHP/Zend作了什麼呢?
1)傳遞給php程序須要的執行文件hello.php,php程序完成基本的準備工做後啓動PHP及Zend引擎,加載註冊的擴展模塊。
2) 初始化完後讀取腳本文件,Zend引擎對腳本進行此詞法分析,語法分析,而後有Zend引擎編譯成opcode碼,最後執行 opcode碼。
php代碼的執行過程以下圖:
php實現了一個典型的動態語言執行過程:拿到一段代碼後,通過詞法解析、語法解析等階段後,源程序會被翻譯成一個個指令(opcodes),而後ZEND虛擬機順次執行這些指令完成操做。PHP自己是用c實現的,所以最終調用的也都是c的函數,實際上,咱們能夠把php看作是一個c開發的軟件。
經過上面描述不難看出,php的執行的核心是翻譯出來的一條一條指令,也即opcode.
解釋器通常包括兩部分:
1)、 讀取源程序,並處理語言結構
2)、處於語言結構並生成目標程序
而Lex和Yacc能夠解決第一個問題。不少編程都有Lex/Yacc做爲語言的詞法語法分析生成器,好比PHP,Python、Ruby已經MySQL的sql語言。
Lex生成詞法分析器。
Yacc語法分析生成器
PHP 構建在Zend虛擬機(Zend VM)之上的,PHP的opcode就是ZEND 虛擬機中的指令,即Opcode是php程序執行的最基本單位。