octobercms 執行php代碼_PHP7語言執行原理

常用的高級語言有很多種,根據運行的方式不同,大體分為兩種:編譯型語言和解釋型語言。

編譯是指在應用源程序執行之前,就將程序源代碼“翻譯”成匯編語言,然后進一步根據軟硬件環境編譯成目標文件。一般稱完成編譯工作的工具為編譯器

而解釋型語言,在程序運行時才被“翻譯”為機器語言。但是執行一次“翻譯”一次,所以執行效率較低。解釋器的工作就是解釋型語言中,負責“翻譯”源代碼的程序。

對于一段C語言代碼,需要經過預編譯、編譯、匯編和鏈接,才能成為可執行的二進制文件。

以C語言為代表的編譯型語言,代碼發生更新都要經過以上步驟。

編譯型語言的執行示意:

974651c4bbf33873ef08ab014c2ed8f3.png

對編譯型語言與解釋型語言的區別的理解,立足于源代碼被編譯成目標平臺CPU指令的時機。對于編譯型語言,編譯結果已經是針對當前CPU體系的指令;而解釋型語言,需要先編譯成中間代碼,再經由該解釋型語言的特定虛擬機,翻譯成特定CPU體系的指令被執行。解釋型語言是在運行過程中,翻譯為目標平臺的指令。常說解釋型語言“慢”,主要也是慢在這里。

在PHP 7中,源代碼首先進行詞法分析,將源代碼切割為多個字符串單元,分割后的字符串稱為Token。而一個一個獨立的Token是無法表達完整語義的,需經過語法分析階段,將Token轉換為抽象語法樹(簡稱AST)。之后,抽象語法樹被轉換為機器指令執行。在PHP中,這些指令稱為opcode。

d30d4e1c5db04cce9e77418327a0deba.png

第1步:源碼通過詞法分析得到Token。
第2步:基于語法分析器生成抽象語法樹(AST)。
第3步:抽象語法樹轉換為opcodes(opcode指令集合),PHP解釋執行opcodes。

e801c4e6879508c838f699ddc7b74e57.png


1.Token
Token是PHP代碼被切割成的有意義的標識。PHP提供了token_get_all()函數來獲取PHP代碼被切割后的Token.。
二維數組的每個成員數組的第一個值為Token對應的枚舉值。第二個值為Token對應的原始字符串內容。第三個值為代碼對應的行號。
可見,Token就是一個個的“詞塊”,但是單獨存在的詞塊不能表達完整的語義,還需要借助規則進行組織串聯。語法分析器就是這個組織者。它會檢查語法,匹配Token,對Token進行關聯。


2.AST
AST是PHP 7版本新特性。在這之前的版本中,PHP代碼的執行過程中是沒有生成AST這一步的。
AST的節點分為多種類型,對應著PHP語法。
PHP-Parser工具,它可以用來查看PHP代碼生成的AST。
注意 PHP-Parser是PHP 7內核作者之一Nikic編寫的將PHP源碼生成AST的工具。源碼見https://github.com/nikic/PHP-Parser


3.opcodes
opcode只是單條指令,opcodes是opcode的集合形式,是PHP執行過程中的中間代碼。opcode生成之后由虛擬機執行。
PHP工程優化措施中有一個比較常見的“開啟opcache”,指的就是這里的opcodes的緩存(opcodes cache)。通過省去從源碼到opcode的階段,引擎可以直接執行緩存的opcode,以此


提升性能。
借助vld插件,可以直觀地看到一段PHP代碼生成的opcode。
opcode是PHP 7定義的一組指令標識,指令對應著相應的handler(處理函數)。當虛擬機調用opcode,會找到opcode背后的處理函數,執行真正的處理。二、內核架構
Zend引擎中包含了編譯器和解釋器,從PHP代碼到opcode的執行,均由Zend引擎完成。
Zend引擎除了實現了PHP的核心功能,還提供了一套接口,讓PHP可以在更多的場景中使用,如命令行環境、Web環境等。

b10166ea39d949e0dddcc27eba7e48d5.png


該架構圖大致分為四大部分。
1)Zend引擎:前文介紹的詞法/語法分析、AST編譯和opcodes的執行均在Zend引擎中實現。此外,PHP的變量設計、內存管理、進程管理等也在引擎層實現。引擎為PHP提供了基礎服務,PHP的可靠性和高性能都依賴引擎的基礎支撐。同時,Zend引擎的可擴展性,還是PHP得以大規模應用的重要原因之一。


2)PHP層:Zend引擎為PHP提供基礎能力(如內存分配和回收),而來自外部的交互則需要通過PHP層來處理。


3)SAPI:SAPI是Server API的縮寫,其中包含了常見的cli SAPI和fpm SAPI。PHP定義好輸入/輸出規范,依據此規范與PHP交互的一方都可以稱為Server。


4)擴展部分:Zend引擎提供了核心能力和接口規范。在此基礎上開發的擴展,為PHP代碼的性能和功能的多樣性提供了更豐富的選項。三、PHP源碼目錄sapi目錄源碼
sapi目錄是對輸入和輸出層的抽象,是PHP提供對外服務的規范。
PHP程序的輸入可以是來自于命令行的標準輸入,也可以是來自基于cgi/fastcgi協議的網絡請求。同理,輸出可以寫到命令行的標準輸出,也可以作為基于cgi/fastcgi協議的網絡響應返回給客戶端。


命令行模式對應的是二進制程序bin/php;內置模塊的模式不需要提供二進制程序,作為普通函數供Apache或任意C/C++程序來調用即可;CGI模式對應的是二進制程序bin/cgi;FastCGI模式對應的是二進制程序sbin/php-fpm。


幾種常用的SAPI。
1)apache2handler:Apache擴展,編譯后生成動態鏈接庫,配置到Apache下,當有http請求到Apache時,根據配置會調用此動態鏈接庫,執行PHP代碼,完成與PHP的交互。


2)cgi-fcgi:編譯后生成支持CGI協議的可執行程序,webserver(通常為Apache或Nginx)通過CGI協議把請求傳給CGI進程,執行代碼將結果返回給webserver,退出進程。
3)fpm-fcgi:fpm全稱為FastCGI Process Manager,PHP官方提供的FastCGI進程管理器。以Nginx服務器為例,當有http協議請求發送到Nginx服務器,Nginx按照FastCGI協議把請求交給php-fpm進程處理。


4)cli:Command Line Interface的簡稱,PHP的命令行交互接口。

Zend目錄源碼
Zend目錄是PHP的核心代碼。
1.內存管理模塊
2.垃圾回收
3.數組實現

main目錄源碼
main目錄是SAPI層和Zend層的黏合劑。
Zend層實現了PHP腳本的編譯和執行,sapi層實現了輸入和輸出的抽象,main目錄則起到了承上啟下的作用:承上,解析SAPI的請求,分析要執行的腳本文件和參數;啟下,調用Zend引擎之前,完成必要的初始化等工作。

ext目錄源碼
ext是PHP擴展相關的目錄,常用的array、str、pdo等系列函數都在這里定義

TSRM目錄源碼
PHP在早期更多的是單個進程、單線程模型運行的,在后期才引入了線程安全機制ZTS(Zend Thread Safety)。
TSRM是Thread Safe Resource Manager的縮寫——線程安全資源管理器。
線程安全機制主要為了保證共享資源的安全。PHP的線程安全機制簡潔直觀——在多線程環境下,為每個線程提供獨立的全局變量副本。具體實施是通過TSRM為每個線程分配(分配前加鎖)一個獨立ID(自增)作為當前線程的全局變量內存區索引,在以后的全局變量訪問中,實現線程之間的完全獨立。

以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那里入手去提升,對此我整理了一些資料,包括但不限于:分布式架構、高可擴展、高性能、高并發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨需要的可以免費分享給大家,需要請戳這里鏈接 或者 知乎專欄
PHP7進階架構師?zhuanlan.zhihu.com
295e50ee53e925d2c1077784797c2ca1.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529139.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529139.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一般程序句柄多少linux,一個進程能夠打開最大文件句柄數設到多大才合適(Linux)...

命令可以看到單個進程能夠打開的最大文件句柄數量(socket連接也算在里面)。系統默認值1024。對于一般的應用來說(象Apache、系統進程)1024完全足夠使用。但是如何象squid、mysql、java等單進程處理大量請求的應用來說就有點捉襟見肘了。如果單個進程打開的文件句柄數量超過了系…

convert.todatetime指定日期格式_JDK1.8新增日期時間類型

如果我們可以跟別人說:“我們在1502643933071見面,別晚了!”那么就再簡單不過了。但是我們希望時間與晝夜和四季有關,于是事情就變復雜了。Java1.0中包含了一個Date類,但是它的大多數方法已經在Java 1.1引入Calendar類…

linux shell運行腳本命令行參數,shell腳本命令行參數簡介

之所以用到命令行參數,關鍵在于shell腳本需要與運行腳本的人員進行交互。bash shell提供了命令行參數添加在命令后面的數據值)、命令行選項修改命令行為的單字符值)和直接讀取鍵盤輸入。1、命令行參數向shell腳本傳遞數據的最基本方式是使用命令行參數。1)讀取參數讀…

eclipse linux遠程調試工具,使用本地Eclipse IDE調試器與遠程項目源(Linux)

我試圖找出以下情況的最佳方法。我有幾個Java源文件正在使用JNI與一些C源代碼進行通信,這些源代碼都駐留在Linux機器上。 Java部分在Linux機器上完美地構建和運行(通過JUnit)。 Java類依賴于幾個Linux(.so)庫。我想在本地計算機(Mac OS X)上運行Eclipse IDE調試器&a…

python下載文件的第三方庫_Python常用第三方庫(轉載)

wxPython 如果你之前是 windows 程序員,用 MFC 或者 WIN32API 開發界面程序,那進入 Python 國度最好的 GUI 選擇應該是 wxPython。它是 wxWidgets 的 Python Bind,與 wxWidgets 的開發完美同步,最為重要的一點是它的消息機制與 MF…

linux sybase 自動備份,Linux平臺下Sybase數據庫備份方法分析.doc

Linux平臺下Sybase數據庫備份方法分析Linux平臺下Sybase數據庫備份方法分析摘 要:對于從事信息系統管理的人員來說,掌握數據庫的備份方法在工作中尤為重要。當本地數據出錯或者磁盤損壞時,可以利用備份的數據恢復數據庫系統,從而保…

facebook對話鏈接_如何應用防錯原則,看看 Facebook 和 Gmail 是怎么做的

歡迎來到有言有料,讓思考更有張力本文共 3873 字,預計閱讀 10 分鐘作者|Siddharth Gulati譯者|張聿彤本文翻譯已獲得作者的正式授權(授權截圖如下)在用戶界面(UI)設計中,重要的是要注意最細微的細節,以使用…

linux 7 定時任務設置,centos7 配置crontab定時任務

1. 啟動cron服務# 查看服務狀態systemctl status crond# 啟動systemctl start crond# 停止systemctl stop crond# 重啟systemctl restart crond# 重新加載systemctl reload crond2. 開機自動啟動cron服務systemctl start crond.service3. 通過crontab命令管理定時任務crontab命…

模擬灰度傳感器循跡的程序_PLC編程,實例講解西門子PLC模擬量編程

給大伙分享的是關于西門子S7-300PLC模擬量方面的實例,包含了以下幾個方面的要點:1、對變送器進行取值,并進行控制2、對模數功能塊 FC105 進行調用3、對 AI 模塊進行設置4、對 AI 量程塊進行選擇這個實例, 調試的是一個流量調節回路…

linux mint 17 輸入法,LinuxMint17.1 Rebecca中安裝設置輸入法

LinuxMint14使用了幾年一直未更新,突然想去更新一下去發現源已經不支持了,所以就直接安裝了最新版本。安裝好以后發現還是跟以前一樣的毛病,沒有中文輸入法,直接sudo aptitude install fcitx* 發現仍然不行。運行im-config設定FCI…

python組成不重復的三位數是多少_Python輸出由1,2,3,4組成的互不相同且無重復的三位數...

題目:有四個數字:1、2、3、4,能組成多少個互不相同且無重復數字的三位數?各是多少? 程序分析:可填在百位、十位、個位的數字都是1、2、3、4。組成所有的排列后再去 掉不滿足條件的排列。 程序源代碼 方法1&…

作業調度C語言編寫,【作業調度方案】 (C語言代碼)

解題思路:如圖所示,對于第一組樣例輸入,按照總工序提供的順序,對于每個工件的工序從小到大,每次尋找有空閑機器的“空檔”插入,就能讓總加工時間最短。注意事項:按照約定,最短方案有且只有一種。參考代碼:#…

python判斷能否組成三角形_python三角形判定怎么做

python三角形判定怎么做?下面給大家帶來具體的例子: 相關推薦:《Python視頻教程》 例子:a int(input("The length of the side a ")) b int(input("The length of the side b ")) c int(input("The…

文件的記錄c語言程序,c語言程序學生籍貫信息記錄簿設計.docx

c 語言程序學生籍貫信息記錄簿設計學生籍貫信息記錄簿課程設計報告書班 級: 方 0909-1 學 號:姓 名: 苑 小 葉 指導教師 : 康 亞 男 石家莊鐵道大學四方學院2010年 07月 14日1課程設計報告內容1. 選擇題目題目: 學生籍貫信息記錄簿設計 2. 內容摘要摘要:學生籍貫信息管理系統是…

如何修改linux的java路徑_修改桌面文件默認存儲位置的正確方式及注意事項

之前寫了篇關于如何修改桌面文件默認存儲位置,許多人在修改后出現各種問題,今天重新來講解一下關于修改桌面文件默認存儲位置的正確方式及注意事項。第一步、在E盤下創建一個文件夾,隨便取個名字,或者默認為【新建文件夾】&#x…

secp256r1 c語言程序,rust代碼閱讀 之 libsecp256k1 (1)

在密碼學的運算中, 數字通常是非常大的. 以 ECDSA 橢圓曲線為例, 私鑰是 256 位的.所以在 libsecp256k1 這個庫里, 定義了計算的元素 Field. 其中 n 為 320 位.pub struct Field {pub(crate) n: [u32; 10],pub(crate) magnitude: u32,pub(crate) normalized: bool,}為其實現加法…

python位運算符_詳細介紹Python語言中的按位運算符

按位運算符是把數字看作二進制來進行計算的。Python中的按位運算法則如下: 按位與 ( bitwise and of x and y ) & 舉例: 5&3 1 解釋: 101 11 相同位僅為個位1 ,故結果為 1 按位或 ( bitwise or of x and y ) | 舉例&…

c語言代碼測試電腦性能,【圖片】今天寫幾個性能測試,為什么C語言跑得這么慢呢??【c語言吧】_百度貼吧...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓易言版本……跑100000萬成績不如PHP。。。。.版本 2.程序集 程序集1.子程序 _啟動子程序, 整數型, , 本子程序在程序啟動后最先執行.局部變量 參數, 文本型, , "0".局部變量 to, 整數型.局部變量 fr, 整數型.局部變量 n,…

python find函數 和index的區別_使用帶有find和index的map時Python2和Python3之間的區別...

給定一個模式和一個字符串str,找到str是否遵循相同的模式. 以下是完全匹配,使得在模式中的字母和str中的非空字之間存在雙射. 例子: pattern “abba”,str “dog cat cat dog”應該返回true;狗是一只貓,貓是b,而這些詞形成了abba模式. pattern “abba”,str “dog c…

c語言3368題目,電大《C語言程序設計課程》期末考試復習資料

0993C 評議程序設計A 第 1 頁 共 31 頁C 語言程序設計課程期末復習練習一、單選題 1.在每個C 語言程序中都必須包含有這樣一個函數,該函數的函數名為( )。A. main 2.每個C 語言程序文件的編譯錯誤分為( )類。B. 2 3. 字符串"ab12\n"…