PHP如何執行 - 從源代碼到渲染
本文由Younes Rafie進行了同行評審。感謝SitePoint所有的同行評審員製作SitePoint內容的最佳狀態!
>受Ruby代碼如何執行的最新文章的啟發,本文涵蓋了PHP代碼的執行過程。
鑰匙要點
PHP代碼的執行涉及四個階段:Lexing,解析,編譯和解釋。每個階段在將PHP源代碼轉換為機器可讀代碼的過程中至關重要。
> Lexing或令牌化是將字符串(PHP源代碼)變成一個令牌序列的過程。每個令牌是其匹配值的命名標識符。此階段還存儲lexeme和匹配令牌的行號。- 驗證令牌順序的有效性,並生成抽象語法樹(AST)。 AST是在編譯階段使用的源代碼的樹視圖。
- 解釋階段是在Zend Engine(ZE)VM上運行Opcodes的最後階段。此階段的輸出是您的PHP腳本通過echo,print,var_dump等命令輸出的內容。 >
- 簡介
- >當我們執行PHP代碼時,引擎蓋下發生了很多事情。從廣義上講,執行代碼時,PHP解釋器將經歷四個階段:
- Lexing
- 解析
彙編
解釋
- >本文將瀏覽這些階段,並展示我們如何查看每個階段的輸出,以真正查看發生了什麼。請注意,雖然某些使用的擴展程序應該已經是您的PHP安裝的一部分(例如Tokenizer和opcache),但需要手動安裝和啟用其他擴展程序(例如,PHP-ast和VLD)。 階段1 - Lexing
- Lexing(或令牌化)是將字符串(在這種情況下為PHP源代碼)轉換為令牌序列的過程。令牌只是其匹配的值的命名標識符。 PHP使用re2c從zend_language_scanner.l定義文件。 >我們可以通過令牌擴展名看到Lexing階段的輸出:
- >輸出:
$code = <<<'code' <span><span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>$tokens = token_get_all($code); </span></span><span> </span><span><span>foreach ($tokens as $token) { </span></span><span> <span>if (is_array($token)) { </span></span><span> <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL; </span></span><span> <span>} else { </span></span><span> <span>var_dump($token); </span></span><span> <span>} </span></span><span><span>} </span></span>
>從上述輸出中有幾個值得注意的點。第一個點是,並非所有源代碼的所有部分都命名為令牌。相反,某些符號本身被視為令牌(例如=,;,:,?等)。第二點是,Lexer實際上做的不只是簡單地輸出一個令牌流。在大多數情況下,它也存儲了lexeme(由令牌匹配的值)和匹配令牌的行號(用於堆棧跟踪之類的內容)。
階段2 - 解析也生成了解析器,這次是通過BNF語法文件與野牛一起生成的。 PHP使用LALR(1)(向前,從左到右)無上下文語法。前面的外觀僅意味著解析器能夠在解析時可能會遇到的歧義。從左到右的部分意味著它從左到右解析令牌流。
>>生成的解析器階段將令牌流從Lexer作為輸入中獲取,並有兩個作業。首先,它通過嘗試將其與BNF語法文件中定義的任何語法規則相匹配,從而驗證令牌順序的有效性。這樣可以確保令牌流中的代幣形成有效的語言構造。解析器的第二個作業是生成
抽象語法樹(AST) - 下一階段將使用的源代碼的樹視圖(彙編)。
我們可以使用php-ast擴展名來查看
Line 1: T_OPEN_TAG ('<?php ') Line 2: T_VARIABLE ('$a') Line 2: T_WHITESPACE (' ') string(1) "=" Line 2: T_WHITESPACE (' ') Line 2: T_LNUMBER ('1') string(1) ";"
$code = <<<'code' <span><span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>print_r(ast<span>\parse_code</span>($code, 30)); </span></span>
>標誌 - 一個指定過載行為的整數(例如,ASTAST_BINARD_OP節點將具有區分發生哪些二進制操作的標誌)
Lineno- lineno - 線號,從較早的令牌信息中可以看出
- 兒童 - 子節點,通常會進一步分解該節點的一部分(例如,功能節點將具有孩子:參數,返回類型,身體等)
- >此階段的AST輸出很方便用於諸如靜態代碼分析儀(例如phan)之類的工具。
階段3 - 彙編
彙編階段消耗了AST,它通過遞歸穿越樹來發出opcods。這個階段還進行了一些優化。這些包括通過字面論據(例如strlen(“ ABC”)到int(3))和折疊持續的數學表達式(例如60 * 60 * 24 to int(86400))。
>我們可以在此階段以多種方式檢查OpCode輸出,包括OPCACHE,VLD和PHPDBG。我將使用VLD為此,因為我覺得輸出更友好。>讓我們看看以下file.php腳本的輸出是什麼:
>$code = <<<'code' <span><span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>$tokens = token_get_all($code); </span></span><span> </span><span><span>foreach ($tokens as $token) { </span></span><span> <span>if (is_array($token)) { </span></span><span> <span>echo "Line <span><span>{$token[2]}</span>: "</span>, token_name($token[0]), " ('<span><span>{$token[1]}</span>')"</span>, PHP_EOL; </span></span><span> <span>} else { </span></span><span> <span>var_dump($token); </span></span><span> <span>} </span></span><span><span>} </span></span>
登入後複製登入後複製Line 1: T_OPEN_TAG ('<?php ') Line 2: T_VARIABLE ('$a') Line 2: T_WHITESPACE (' ') string(1) "=" Line 2: T_WHITESPACE (' ') Line 2: T_LNUMBER ('1') string(1) ";"
登入後複製登入後複製> OPCACHE不僅可以簡單地緩存OPCODE(因此繞過Lexing,解析和編譯階段)。它還包含許多不同級別的優化。讓我們將優化級別提高到四個傳球,以查看出來的內容:$code = <<<'code' <span><span><?php </span></span><span><span>$a = 1; </span></span><span>code<span>; </span></span><span> </span><span><span>print_r(ast<span>\parse_code</span>($code, 30)); </span></span>
登入後複製登入後複製>
>命令:>輸出:
ast\Node Object ( [kind] => 132 [flags] => 0 [lineno] => 1 [children] => Array ( [0] => ast\Node Object ( [kind] => 517 [flags] => 0 [lineno] => 2 [children] => Array ( [var] => ast\Node Object ( [kind] => 256 [flags] => 0 [lineno] => 2 [children] => Array ( [name] => a ) ) [expr] => 1 ) ) ) )
登入後複製>我們可以看到恆定條件已被刪除,並且兩個迴聲指令已被壓縮到單個指令中。這些只是對Opcache在腳本的Opcodes上進行的許多優化的味道。不過,我不會瀏覽本文的各種優化級別,因為這本身也是一篇文章。
>階段4 - 解釋<span>if (PHP_VERSION === '7.1.0-dev') { </span> <span>echo 'Yay', PHP_EOL; </span><span>} </span>
登入後複製>最後階段是對opcodes的解釋。這是Opcodes在Zend Engine(ZE)VM上運行的地方。對於這個階段,實際上幾乎沒有什麼可說的(至少從高級角度來看)。輸出幾乎是您通過echo,print,var_dump等命令輸出輸出的任何內容。
>因此,這是一個有趣的事實,而不是在此階段挖掘任何復雜的事實:PHP在生成自己的VM時需要自己作為依賴性。這是因為VM是由PHP腳本生成的,因為它更簡單並且更易於維護。結論
>我們已經簡要介紹了PHP解釋器在運行PHP代碼時通過的四個階段。這涉及使用各種擴展(包括令牌,PHP-ast,opcache和vld)來操縱和查看每個階段的輸出。
。>我希望本文能夠幫助您對PHP的解釋器有更好的整體理解,並顯示了Opcache擴展的重要性(用於其緩存和優化能力)。
經常詢問有關PHP執行過程的問題(常見問題解答)>
> PHP的命令行接口和Web服務器接口之間有什麼區別? -line接口(CLI)和Web服務器接口是運行PHP腳本的兩種不同方法。 CLI用於從命令行運行PHP腳本,而Web服務器接口則用於響應Web請求來運行PHP腳本。兩個接口之間的主要區別是它們處理輸入和輸出的方式。在CLI中,從命令行讀取輸入,並將輸出寫入控制台。在Web服務器接口中,從HTTP請求讀取輸入,並將輸出寫入HTTP響應。>
PHP在執行過程中如何處理錯誤?php具有強大的錯誤處理。允許其在執行過程中處理錯誤的機制。發生錯誤時,PHP會生成錯誤消息並將其發送到錯誤處理程序。錯誤處理程序可以根據錯誤報告設置顯示錯誤消息,將其記錄或忽略。 PHP還支持異常處理,這使其可以以更結構化和易於管理的方式處理錯誤。 > > php擴展在執行過程中的作用是什麼?
php擴展是在PHP語言中添加新功能和功能的模塊。在執行過程中,它們被加載到PHP運行時環境中,可用於執行從數據庫訪問到圖像處理的廣泛任務。 PHP擴展名為C編寫,並編譯為機器代碼,這使其非常快速有效。它們是PHP生態系統的關鍵組成部分,並有助於其靈活性和功率。
>> PHP如何優化執行過程?
PHP使用多種技術來優化執行過程。這些技術之一是OpCode緩存,其中涉及將PHP引擎生成的字節碼存儲在內存中,以便可以在後續執行中重複使用。這消除了每次執行PHP腳本的必要性,從而大大提高了性能。 PHP還使用Just-In-time(JIT)彙編,其中涉及在運行時將字節碼編譯到機器代碼中以進一步提高性能。>
PHP在執行過程中如何處理內存管理? PHP具有內置內存管理器,可以在執行過程中處理內存分配和Deallocation。內存管理器根據需要為變量和數據結構分配內存,並在不再需要內存時對內存進行交易。 PHP還具有一個垃圾收集器,該垃圾收集器會自動釋放不再使用的內存。這有助於防止內存洩漏並將內存使用控制在控制之下。 > Web服務器在PHP執行過程中的作用是什麼?>
> Web服務器在PHP執行中起關鍵作用過程。它負責處理HTTP請求,對這些請求運行PHP腳本,然後將HTTP響應發送回客戶端。 Web服務器與PHP解釋器和PHP引擎緊密合作,以執行PHP腳本並生成動態網頁。 PHP最常用的Web服務器是Apache和Nginx。 MySQL,PostgreSQL和SQLite。它在執行過程中使用數據庫特異性擴展與這些數據庫進行交互。這些擴展提供了一組功能,可用於連接到數據庫,執行SQL查詢,獲取結果並處理錯誤。 PHP還支持PDO(PHP數據對象)擴展名,該擴展提供了數據庫交互的數據庫-Nostic接口。> PHP在執行過程中如何處理會話管理?
PHP對會話管理具有內置支持,這使其可以在不同的HTTP請求之間維護狀態。啟動會話後,PHP會創建唯一的會話ID,並將其存儲在客戶端瀏覽器上的cookie中。然後,此會話ID通過每個後續請求發送回服務器,允許PHP識別客戶端並檢索相應的會話數據。 PHP的會話管理功能使在Web應用程序中實現用戶身份驗證,購物車和其他狀態功能變得易於實現。
以上是PHP如何執行 - 從源代碼到渲染的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
