ホームページ  >  記事  >  バックエンド開発  >  PHP 原則の深い理解: Opcodes_PHP チュートリアル

PHP 原則の深い理解: Opcodes_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 17:46:17852ブラウズ

Opcode は、Java の ByteCode や .NET の MSL と同様に、PHP スクリプトからコンパイルされた中間言語です。たとえば、次の PHP コードを作成するとします。

「ハローワールド」をエコーし​​ます

$a = 1 + 1;

$a をエコーし​​ます。

PHP はこのコードを実行するために次の 4 つのステップを経ます (正確には、PHP の言語エンジン Zend のはずです)

1. スキャン(レクシング)、PHPコードを言語フラグメント(トークン)に変換します

2. トークンを解析し、シンプルで意味のある表現に変換します

3. コンパイル、式を Opocdes にコンパイルします

4. 実行。オペコードを一度に 1 つずつ順番に実行し、PHP スクリプトの機能を実現します。

注: APC などの一部のキャッシュを使用すると、PHP がオペコードをキャッシュできるようになります。これにより、リクエストが届くたびに最初の 3 つの手順を繰り返す必要がなくなり、PHP の実行速度が大幅に向上します。

では、字句解析とは何でしょうか? コンパイルの原理を学習した学生は、字句解析の基本テーブルであるコンパイルの原理を理解しているはずです。 Zend/zend_ language_scanner.c は、Zend/zend_ language_scanner.l (Lex ファイル) を元に入力された PHP コードを字句解析し、「単語」を 1 つずつ取得する機能です。 PHP コードの一部をスキャンしてトークンにすることについて;

この関数を使用して冒頭で説明した PHP コードを処理すると、次の結果が得られます:

配列

(

[0] => 配列

(

[0] => 367

[1] =>

(

[0] = > 316

[1] => エコー

)

[2] => 配列

(

[0] => 370

[1] =>

)

[3] => 配列

(

[0] = > 315

「ハローワールド」[1] =>

)

[4] => ;

[5] => 配列

(

[0] => 370

[1] =>

)

[6] => =

[7] => 配列

(

[0] => 370

[1] =>

)

[8] => 配列

(

[0] = > 305

 

            [1] => 1

 

        )

 

    [9] =>配列

 

        (

 

            [0] => 370

 

            [1] => 

 

        )

 

    [10] => +

 

    [11] =>配列

 

        (

 

            [0] => 370

 

            [1] => 

 

        )

 

    [12] =>配列

 

        (

 

            [0] => 305

 

            [1] => 1

 

        )

 

    [13] => ; 

 

    [14] =>配列

 

        (

 

            [0] => 370

 

            [1] => 

 

        )

 

    [15] =>配列

 

        (

 

            [0] => 316

 

            [1] =>エコー

 

        )

 

    [16] =>配列

 

        (

 

            [0] => 370

 

            [1] => 

 

        )

 

    [17] => ; 

 

)

 

 

 

この返された結果を分析すると、ソース コード内の文字列、文字、空格、シティ ソースが返されることがわかりました。各ソース コード内の文字、シティは、対応する順序で返されます。シティは、トークン ID (つまり、T_ECHO、T_STRING などの Zend 内部の変更トークンの対コード)、およびソースコード内の元のコンテンツを含む配列に変換されます。

 

  次に、これは解析段階が完了し、最初にトークン配列内の複数の空格を解析し、その後、残りのトークンを 1 つの単一の表形式に変換します

 

1. 定数文字列をエコーする

 

2. 2 つの数値を加算します

 

3. 前の式の結果を変数に保存します

 

4. 変数をエコーする

 

 

 

その後、コンパイル段階が変更され、トークンが 1 つの op_array に変換され、op_arrayd には次の 5 つの部分が含まれます:

 

1. オペコード番号の標識、op_array の操作の種類を示す、add 、 echo

と比較

 

2. 結果 存続オペコード結果

 

3. 操作数1 オペコードの操作数

 

4. 操作数2

 

5. 拡張値 1 の整数は、オーバーロードされた演算子を区別するために使用されます

たとえば、PHP コードは次のように解析されます:

ZEND_ECHO「ハローワールド」

ZEND_ADD ~0 1 1

ZEND_ASSIGN !0 ~0

ZEND_ECHO !0

ははは、私たちの$aはどこに行ったのかと疑問に思うかもしれません。

これは、各オペランドの紹介であり、次の 2 つの部分で構成されます。

a) op_type: IS_CONST、IS_TMP_VAR、IS_VAR、IS_UNUSED、または IS_CV

b) u、共用体は、このオペランドの値 (const) または左辺値 (var) を、op_type の違いに従って異なる型で格納します

varに関しては、それぞれのvarが異なります

IS_TMP_VAR は、名前が示すように、次の op_array で使用するために op_array の結果を保存する一時変数です。このタイプのオペランドの u は、通常、変数テーブルを指すハンドル (整数) を格納します。 used~ ~0などの先頭は変数テーブルの未知の一時変数No.0を示します

IS_VAR は変数の一般的な意味であり、$

で始まります。

IS_CV は、ZE2.1/PHP5.1 以降のコンパイラで使用されるキャッシュ メカニズムを表します。この変数は、変数が初めて参照されるときに、この変数が参照される際にその変数のアドレスを格納します。アクティブなシンボル テーブルを再度検索する必要はありません。CV 変数は で始まります。始まりはそれを示しています。

$a は参照されていないため、!0 に最適化されているようです。

・作者:ラルエンス(http://www.laruence.com/)

http://www.bkjia.com/PHPjc/478609.htmlwww.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/478609.html技術記事オペコードは、Java の ByteCode や .NET の MSL と同様に、PHP スクリプトからコンパイルされた中間言語です。たとえば、次のような PHP コードを作成するとします。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。