<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                在前面的章節介紹了PHP的生命周期,PHP的SAPI,SAPI處于PHP整個架構較上層,而真正腳本的執行主要由Zend引擎來完成,這一小節我們介紹PHP腳本的執行。 目前編程語言可以分為兩大類: - 第一類是像C/C++, .NET, Java之類的編譯型語言, 它們的共性是: 運行之前必須對源代碼進行編譯,然后運行編譯后的目標文件。 - 第二類比如:PHP, Javascript, Ruby, Python這些解釋型語言, 他們都無需經過編譯即可"運行",雖然可以理解為直接運行, 但它們并不是真的直接就被能被機器理解, 機器只能理解機器語言,那這些語言是怎么被執行的呢, 一般這些語言都需要一個**解釋器**,由解釋器來執行這些源碼, 實際上這些語言還是會經過編譯環節,只不過它們一般會在運行的時候實時進行編譯。為了效率,并不是所有語言在每次執行的時候都會重新編譯一遍,比如PHP的各種opcode緩存擴展(如APC, xcache, eAccelerator等),比如Python會將編譯的中間文件保存成pyc/pyo文件,避免每次運行重新進行編譯所帶來的性能損失。 PHP的腳本的執行也需要一個解釋器, 比如命令行下的php程序,或者apache的mod_php模塊等等。前一節提到了PHP的SAPI接口, 下面就以PHP命令行程序為例解釋PHP腳本是怎么被執行的。例如如下的這段PHP腳本: <?php $str = "Hello, Tipi!\n"; [echo](http://www.php.net/echo) $str; 假設上面的代碼保存在名為hello.php的文件中, 用PHP命令行程序執行這個腳本: $ php ./hello.php 這段代碼的輸出顯然是Hello, Tipi!, 那么在執行腳本的時候PHP/Zend都做了些什么呢?這些語句是怎么樣讓php輸出這段話的呢? 下面將一步一步的進行介紹。 ## 程序的執行 1. 如上例中, 傳遞給php程序需要執行的文件, php程序完成基本的準備工作后啟動PHP及Zend引擎, 加載注冊的擴展模塊。 1. 初始化完成后讀取腳本文件,Zend引擎對腳本文件進行詞法分析,語法分析。然后編譯成opcode執行。 如果安裝了apc之類的opcode緩存,編譯環節可能會被跳過而直接從緩存中讀取opcode執行。 ### 腳本的編譯執行 PHP在讀取到腳本文件后首先對代碼進行詞法分析,PHP的詞法分析器是通過lex生成的, 詞法規則文件在$PHP_SRC/Zend/zend_language_scanner.l,這一階段lex會會將源代碼按照詞法規則切分一個一個的標記(token)。PHP中提供了一個函數token_get_all(),該函數接收一個字符串參數, 返回一個按照詞法規則切分好的數組。例如將上面的php代碼作為參數傳遞給這個函數: <?php $code =<<<PHP_CODE <?php $str = "Hello, Tipi\n"; echo $str; PHP_CODE; ? [var_dump](http://www.php.net/var_dump)([token_get_all](http://www.php.net/token_get_all)($code)); 運行上面的腳本你將會看到一如下的輸出 array ( 0 => array ( 0 => 368, // 腳本開始標記 1 => '<?php // 匹配到的字符串 ', 2 => 1, ), 1 => array ( 0 => 371, 1 => ' ', 2 => 2, ), 2 => '=', 3 => array ( 0 => 371, 1 => ' ', 2 => 2, ), 4 => array ( 0 => 315, 1 => '"Hello, Tipi "', 2 => 2, ), 5 => ';', 6 => array ( 0 => 371, 1 => ' ', 2 => 3, ), 7 => array ( 0 => 316, 1 => 'echo', 2 => 4, ), 8 => array ( 0 => 371, 1 => ' ', 2 => 4, ), 9 => ';', 這也是Zend引擎詞法分析做的事情,將代碼切分為一個個的標記,然后使用語法分析器(PHP使用bison生成語法分析器, 規則見$PHP_SRC/Zend/zend_language_parser.y),bison根據規則進行相應的處理, 如果代碼找不到匹配的規則,也就是語法錯誤時Zend引擎會停止,并輸出錯誤信息。 比如缺少括號,或者不符合語法規則的情況都會在這個環節檢查。在匹配到相應的語法規則后,Zend引擎還會進行編譯, 將代碼編譯為opcode, 完成后,Zend引擎會執行這些opcode, 在執行opcode的過程中還有可能會繼續重復進行編譯-執行,例如執行eval,include/require等語句, 因為這些語句還會包含或者執行其他文件或者字符串中的腳本。 例如上例中的echo語句會編譯為一條ZEND_ECHO指令, 執行過程中,該指令由C函數zend_print_variable(zval* z)執行,將傳遞進來的字符串打印出來。為了方便理解, 本例中省去了一些細節,例如opcode指令和處理函數之間的映射關系等。 后面的章節將會詳細介紹。 如果想直接查看生成的Opcode,可以使用php的vld擴展查看。擴展下載地址: [http://pecl.php.net/package/vld](http://pecl.php.net/package/vld)。Win下需要自己編譯生成dll文件。 有關PHP腳本編譯執行的細節,請閱讀后面有關詞法分析,語法分析及opcode編譯相關內容。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看