亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
匯編
階段3 - 匯編
結(jié)論
>
> PHP在執(zhí)行過程中如何處理會話管理?
首頁 后端開發(fā) php教程 PHP如何執(zhí)行 - 從源代碼到渲染

PHP如何執(zhí)行 - 從源代碼到渲染

Feb 10, 2025 am 10:11 AM

PHP如何執(zhí)行 - 從源代碼到渲染

本文由Younes Rafie進行了同行評審。感謝SitePoint所有的同行評審員制作SitePoint內(nèi)容的最佳狀態(tài)!


>受Ruby代碼如何執(zhí)行的最新文章的啟發(fā),本文涵蓋了PHP代碼的執(zhí)行過程。

PHP如何執(zhí)行 - 從源代碼到渲染鑰匙要點

PHP代碼的執(zhí)行涉及四個階段:Lexing,解析,編譯和解釋。每個階段在將PHP源代碼轉(zhuǎn)換為機器可讀代碼的過程中至關(guān)重要。

> Lexing或令牌化是將字符串(PHP源代碼)變成一個令牌序列的過程。每個令牌是其匹配值的命名標(biāo)識符。此階段還存儲lexeme和匹配令牌的行號。> 解析階段
    驗證令牌順序的有效性,并生成抽象語法樹(AST)。 AST是在編譯階段使用的源代碼的樹視圖。 匯編階段通過遍歷AST并進行優(yōu)化,例如使用字面參數(shù)和折疊恒定的數(shù)學(xué)表達式進行優(yōu)化??梢允褂肙PCACHE,VLD和PHPDBG檢查此階段的輸出。
  • 解釋階段是在Zend Engine(ZE)VM上運行Opcodes的最后階段。此階段的輸出是您的PHP腳本通過echo,print,var_dump等命令輸出的內(nèi)容。
  • >
  • 簡介
  • >當(dāng)我們執(zhí)行PHP代碼時,引擎蓋下發(fā)生了很多事情。從廣義上講,執(zhí)行代碼時,PHP解釋器將經(jīng)歷四個階段:>
  • Lexing
  • 解析

匯編

解釋

  1. >本文將瀏覽這些階段,并展示我們?nèi)绾尾榭疵總€階段的輸出,以真正查看發(fā)生了什么。請注意,雖然某些使用的擴展程序應(yīng)該已經(jīng)是您的PHP安裝的一部分(例如Tokenizer和opcache),但需要手動安裝和啟用其他擴展程序(例如,PHP-ast和VLD)。
  2. 階段1 - Lexing
  3. Lexing(或令牌化)是將字符串(在這種情況下為PHP源代碼)轉(zhuǎn)換為令牌序列的過程。令牌只是其匹配的值的命名標(biāo)識符。 PHP使用re2c從zend_language_scanner.l定義文件。
  4. >我們可以通過令牌擴展名看到Lexing階段的輸出:
  5. >輸出:
  6. $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實際上做的不只是簡單地輸出一個令牌流。在大多數(shù)情況下,它也存儲了lexeme(由令牌匹配的值)和匹配令牌的行號(用于堆棧跟蹤之類的內(nèi)容)。

    階段2 - 解析

    也生成了解析器,這次是通過BNF語法文件與野牛一起生成的。 PHP使用LALR(1)(向前,從左到右)無上下文語法。前面的外觀僅意味著解析器能夠在解析時可能會遇到的歧義。從左到右的部分意味著它從左到右解析令牌流。

    >

    >生成的解析器階段將令牌流從Lexer作為輸入中獲取,并有兩個作業(yè)。首先,它通過嘗試將其與BNF語法文件中定義的任何語法規(guī)則相匹配,從而驗證令牌順序的有效性。這樣可以確保令牌流中的代幣形成有效的語言構(gòu)造。解析器的第二個作業(yè)是生成

    抽象語法樹

    (AST) - 下一階段將使用的源代碼的樹視圖(匯編)。 我們可以使用php-ast擴展名來查看的一種

    。內(nèi)部AST并沒有直接暴露,因為與之合作(在一致性和一般可用性方面)并不是特別“干凈”,因此PHP-AST擴展對其進行了一些轉(zhuǎn)換以使其可以更好地使用。 >讓我們看一下基本代碼的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) ";"
    
    樹節(jié)點(通常是類型的astnode)具有多個屬性:

    $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>
    類型 - 描繪節(jié)點類型的整數(shù)值;每個都有相應(yīng)的常數(shù)(例如AST_STMT_LIST => 132,AST_ASSIGN => 517,AST_VAR => 256)

    >標(biāo)志 - 一個指定過載行為的整數(shù)(例如,ASTAST_BINARD_OP節(jié)點將具有區(qū)分發(fā)生哪些二進制操作的標(biāo)志)

    Lineno
    lineno - 線號,從較早的令牌信息中可以看出
  • 兒童 - 子節(jié)點,通常會進一步分解該節(jié)點的一部分(例如,功能節(jié)點將具有孩子:參數(shù),返回類型,身體等)
  • >此階段的AST輸出很方便用于諸如靜態(tài)代碼分析儀(例如phan)之類的工具。

    階段3 - 匯編

    匯編階段消耗了AST,它通過遞歸穿越樹來發(fā)出opcods。這個階段還進行了一些優(yōu)化。這些包括通過字面論據(jù)(例如strlen(“ ABC”)到int(3))和折疊持續(xù)的數(shù)學(xué)表達式(例如60 * 60 * 24 to int(86400))。

    >我們可以在此階段以多種方式檢查OpCode輸出,包括OPCACHE,VLD和PHPDBG。我將使用VLD為此,因為我覺得輸出更友好。

    >讓我們看看以下file.php腳本的輸出是什么:

    執(zhí)行以下命令:
    $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) ";"
    

    > Opcodes類似于原始源代碼,足以與基本操作一起進行。 (我不會深入研究本文中的opcodes的詳細信息,因為這本身將需要幾個整個文章。)在上面腳本中沒有在OpCode級別上應(yīng)用優(yōu)化,但是正如我們所看到的,編譯階段通過解決恒定條件(php_version ==='7.1.0-dev')來做出一些。
    $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>
    > OPCACHE不僅可以簡單地緩存OPCODE(因此繞過Lexing,解析和編譯階段)。它還包含許多不同級別的優(yōu)化。讓我們將優(yōu)化級別提高到四個傳球,以查看出來的內(nèi)容:

    >

    >命令:

    >輸出:

    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上進行的許多優(yōu)化的味道。不過,我不會瀏覽本文的各種優(yōu)化級別,因為這本身也是一篇文章。

    >階段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等命令輸出輸出的任何內(nèi)容。

    >因此,這是一個有趣的事實,而不是在此階段挖掘任何復(fù)雜的事實:PHP在生成自己的VM時需要自己作為依賴性。這是因為VM是由PHP腳本生成的,因為它更簡單并且更易于維護。

    結(jié)論

    >我們已經(jīng)簡要介紹了PHP解釋器在運行PHP代碼時通過的四個階段。這涉及使用各種擴展(包括令牌,PHP-ast,opcache和vld)來操縱和查看每個階段的輸出。

    >我希望本文能夠幫助您對PHP的解釋器有更好的整體理解,并顯示了Opcache擴展的重要性(用于其緩存和優(yōu)化能力)。

    經(jīng)常詢問有關(guān)PHP執(zhí)行過程的問題(常見問題解答)

    > PHP解釋器在執(zhí)行過程中的作用是什么?它負責(zé)將PHP源代碼轉(zhuǎn)換為機器可讀代碼。解釋器逐行讀取PHP腳本,解釋每行并執(zhí)行必要的操作。它還負責(zé)在執(zhí)行過程中處理錯誤和例外。 PHP解釋器是PHP運行時環(huán)境的關(guān)鍵組成部分,其中還包括Web服務(wù)器和PHP擴展。 PHP執(zhí)行過程。它負責(zé)解析PHP腳本,將其編譯到字節(jié)碼中,然后執(zhí)行字節(jié)碼。 PHP引擎使用兩步過程來執(zhí)行PHP腳本。首先,它解析PHP腳本并將其轉(zhuǎn)換為抽象語法樹(AST)。然后,將AST編譯到字節(jié)碼中并執(zhí)行。 PHP引擎還包括一個內(nèi)存管理器和一個垃圾收集器,以在執(zhí)行過程中管理內(nèi)存使用量。

    >

    > PHP的命令行接口和Web服務(wù)器接口之間有什么區(qū)別? -line接口(CLI)和Web服務(wù)器接口是運行PHP腳本的兩種不同方法。 CLI用于從命令行運行PHP腳本,而Web服務(wù)器接口則用于響應(yīng)Web請求來運行PHP腳本。兩個接口之間的主要區(qū)別是它們處理輸入和輸出的方式。在CLI中,從命令行讀取輸入,并將輸出寫入控制臺。在Web服務(wù)器接口中,從HTTP請求讀取輸入,并將輸出寫入HTTP響應(yīng)。

    >

    PHP在執(zhí)行過程中如何處理錯誤?

    php具有強大的錯誤處理。允許其在執(zhí)行過程中處理錯誤的機制。發(fā)生錯誤時,PHP會生成錯誤消息并將其發(fā)送到錯誤處理程序。錯誤處理程序可以根據(jù)錯誤報告設(shè)置顯示錯誤消息,將其記錄或忽略。 PHP還支持異常處理,這使其可以以更結(jié)構(gòu)化和易于管理的方式處理錯誤。>

    > php擴展在執(zhí)行過程中的作用是什么?

    php擴展是在PHP語言中添加新功能和功能的模塊。在執(zhí)行過程中,它們被加載到PHP運行時環(huán)境中,可用于執(zhí)行從數(shù)據(jù)庫訪問到圖像處理的廣泛任務(wù)。 PHP擴展名為C編寫,并編譯為機器代碼,這使其非常快速有效。它們是PHP生態(tài)系統(tǒng)的關(guān)鍵組成部分,并有助于其靈活性和功率。

    >

    > PHP如何優(yōu)化執(zhí)行過程?

    PHP使用多種技術(shù)來優(yōu)化執(zhí)行過程。這些技術(shù)之一是OpCode緩存,其中涉及將PHP引擎生成的字節(jié)碼存儲在內(nèi)存中,以便可以在后續(xù)執(zhí)行中重復(fù)使用。這消除了每次執(zhí)行PHP腳本的必要性,從而大大提高了性能。 PHP還使用Just-In-time(JIT)匯編,其中涉及在運行時將字節(jié)碼編譯到機器代碼中以進一步提高性能。

    >

    PHP在執(zhí)行過程中如何處理內(nèi)存管理? PHP具有內(nèi)置內(nèi)存管理器,可以在執(zhí)行過程中處理內(nèi)存分配和Deallocation。內(nèi)存管理器根據(jù)需要為變量和數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,并在不再需要內(nèi)存時對內(nèi)存進行交易。 PHP還具有一個垃圾收集器,該垃圾收集器會自動釋放不再使用的內(nèi)存。這有助于防止內(nèi)存泄漏并將內(nèi)存使用控制在控制之下。

    > Web服務(wù)器在PHP執(zhí)行過程中的作用是什么?

    >

    > Web服務(wù)器在PHP執(zhí)行中起關(guān)鍵作用過程。它負責(zé)處理HTTP請求,對這些請求運行PHP腳本,然后將HTTP響應(yīng)發(fā)送回客戶端。 Web服務(wù)器與PHP解釋器和PHP引擎緊密合作,以執(zhí)行PHP腳本并生成動態(tài)網(wǎng)頁。 PHP最常用的Web服務(wù)器是Apache和Nginx。 MySQL,PostgreSQL和SQLite。它在執(zhí)行過程中使用數(shù)據(jù)庫特異性擴展與這些數(shù)據(jù)庫進行交互。這些擴展提供了一組功能,可用于連接到數(shù)據(jù)庫,執(zhí)行SQL查詢,獲取結(jié)果并處理錯誤。 PHP還支持PDO(PHP數(shù)據(jù)對象)擴展名,該擴展提供了數(shù)據(jù)庫交互的數(shù)據(jù)庫-Nostic接口。

    > PHP在執(zhí)行過程中如何處理會話管理?

    PHP對會話管理具有內(nèi)置支持,這使其可以在不同的HTTP請求之間維護狀態(tài)。啟動會話后,PHP會創(chuàng)建唯一的會話ID,并將其存儲在客戶端瀏覽器上的cookie中。然后,此會話ID通過每個后續(xù)請求發(fā)送回服務(wù)器,允許PHP識別客戶端并檢索相應(yīng)的會話數(shù)據(jù)。 PHP的會話管理功能使在Web應(yīng)用程序中實現(xiàn)用戶身份驗證,購物車和其他狀態(tài)功能變得易于實現(xiàn)。

以上是PHP如何執(zhí)行 - 從源代碼到渲染的詳細內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
PHP變量范圍解釋了 PHP變量范圍解釋了 Jul 17, 2025 am 04:16 AM

PHP變量作用域常見問題及解決方法包括:1.函數(shù)內(nèi)部無法訪問全局變量,需使用global關(guān)鍵字或參數(shù)傳入;2.靜態(tài)變量用static聲明,只初始化一次并在多次調(diào)用間保持值;3.超全局變量如$_GET、$_POST可在任何作用域直接使用,但需注意安全過濾;4.匿名函數(shù)需通過use關(guān)鍵字引入父作用域變量,修改外部變量則需傳遞引用。掌握這些規(guī)則有助于避免錯誤并提升代碼穩(wěn)定性。

如何在PHP中牢固地處理文件上傳? 如何在PHP中牢固地處理文件上傳? Jul 08, 2025 am 02:37 AM

要安全處理PHP文件上傳需驗證來源與類型、控制文件名與路徑、設(shè)置服務(wù)器限制并二次處理媒體文件。1.驗證上傳來源通過token防止CSRF并通過finfo_file檢測真實MIME類型使用白名單控制;2.重命名文件為隨機字符串并根據(jù)檢測類型決定擴展名存儲至非Web目錄;3.PHP配置限制上傳大小及臨時目錄Nginx/Apache禁止訪問上傳目錄;4.GD庫重新保存圖片清除潛在惡意數(shù)據(jù)。

在PHP中評論代碼 在PHP中評論代碼 Jul 18, 2025 am 04:57 AM

PHP注釋代碼常用方法有三種:1.單行注釋用//或#屏蔽一行代碼,推薦使用//;2.多行注釋用/.../包裹代碼塊,不可嵌套但可跨行;3.組合技巧注釋如用/if(){}/控制邏輯塊,或配合編輯器快捷鍵提升效率,使用時需注意閉合符號和避免嵌套。

發(fā)電機如何在PHP中工作? 發(fā)電機如何在PHP中工作? Jul 11, 2025 am 03:12 AM

AgeneratorinPHPisamemory-efficientwaytoiterateoverlargedatasetsbyyieldingvaluesoneatatimeinsteadofreturningthemallatonce.1.Generatorsusetheyieldkeywordtoproducevaluesondemand,reducingmemoryusage.2.Theyareusefulforhandlingbigloops,readinglargefiles,or

撰寫PHP評論的提示 撰寫PHP評論的提示 Jul 18, 2025 am 04:51 AM

寫好PHP注釋的關(guān)鍵在于明確目的與規(guī)范,注釋應(yīng)解釋“為什么”而非“做了什么”,避免冗余或過于簡單。1.使用統(tǒng)一格式,如docblock(/*/)用于類、方法說明,提升可讀性與工具兼容性;2.強調(diào)邏輯背后的原因,如說明為何需手動輸出JS跳轉(zhuǎn);3.在復(fù)雜代碼前添加總覽性說明,分步驟描述流程,幫助理解整體思路;4.合理使用TODO和FIXME標(biāo)記待辦事項與問題,便于后續(xù)追蹤與協(xié)作。好的注釋能降低溝通成本,提升代碼維護效率。

快速PHP安裝教程 快速PHP安裝教程 Jul 18, 2025 am 04:52 AM

ToinstallPHPquickly,useXAMPPonWindowsorHomebrewonmacOS.1.OnWindows,downloadandinstallXAMPP,selectcomponents,startApache,andplacefilesinhtdocs.2.Alternatively,manuallyinstallPHPfromphp.netandsetupaserverlikeApache.3.OnmacOS,installHomebrew,thenrun'bre

如何通過php中的索引訪問字符串中的字符 如何通過php中的索引訪問字符串中的字符 Jul 12, 2025 am 03:15 AM

在PHP中獲取字符串特定索引字符可用方括號或花括號,但推薦方括號;索引從0開始,超出范圍訪問返回空值,不可賦值;處理多字節(jié)字符需用mb_substr。例如:$str="hello";echo$str[0];輸出h;而中文等字符需用mb_substr($str,1,1)獲取正確結(jié)果;實際應(yīng)用中循環(huán)訪問前應(yīng)檢查字符串長度,動態(tài)字符串需驗證有效性,多語言項目建議統(tǒng)一使用多字節(jié)安全函數(shù)。

學(xué)習(xí)PHP:初學(xué)者指南 學(xué)習(xí)PHP:初學(xué)者指南 Jul 18, 2025 am 04:54 AM

易于效率,啟動啟動tingupalocalserverenverenvirestoolslikexamppandacodeeditorlikevscode.1)installxamppforapache,mysql,andphp.2)uscodeeditorforsyntaxssupport.3)

See all articles