ホームページ  >  記事  >  バックエンド開発  >  PHP の OpCode 原理の詳細な説明

PHP の OpCode 原理の詳細な説明

墨辰丷
墨辰丷オリジナル
2018-06-02 09:29:061882ブラウズ

この記事は主にPHPのOpCode原理を紹介し、関連するコンパイルメカニズムとPHPプログラムの動作原理をより詳細に分析します。必要な友人はそれを参照してください

OpCodeはJava ByteCodeと同じように、PHPスクリプトによってコンパイルされる中間言語です。 、または .NET の MSL。 この記事は主に「OPcode の理解」とインターネットに基づいて個人的な理解と修正に基づいて記録されています:

PHP コード:

PHP はこのコードを実行するために次の 4 つの手順を実行します。

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 つずつ取得します。PHP4.2 以降では、token_get_all と呼ばれる関数が提供されます。この関数は、PHP コードの一部をトークンにスキャンできます。

<?php
  echo "Hello World";
  $a = 1 + 1;
  echo $a;
?>

は次の結果を取得します:

返された結果、ソース コード内の文字列、文字、スペースは変更されません。戻る。各ソース コード内の文字は、対応する順序で表示されます。ただし、タグ、演算子、ステートメントなどの他の項目は、トークン ID (つまり、T_ECHO、T_STRING など、Zend 内のトークンを変更するための対応するコード) と元のコードの 2 つの部分を含む配列に変換されます。ソースコード。

次のステップは解析段階です。解析では、まずトークン配列内の余分なスペースが破棄され、次に残りのトークンが 1 つずつ単純な式に変換されます

1。2 つの数値を加算します。 3. 前の式の結果を変数に保存します

4. 変数をエコーし​​ます

次に、トークンを 1 つずつ op_array にコンパイルします:


1.オペコード番号の識別は、add、echo
2 などの各 op_array の操作タイプを示します。結果には、Opcode の結果
3 が格納されます。Operand 2 のオペランド

5 は整数です。オーバーロードされた演算子を区別するために使用されます

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



Array
(
  [0] => Array
    (
      [0] => 367
      [1] => <?php
      [2] => 1
    )
  [1] => Array
    (
      [0] => 370
      [1] =>
      [2] => 2
    )
  [2] => Array
    (
      [0] => 316
      [1] => echo
      [2] => 2
    )
  [3] => Array
    (
      [0] => 370
      [1] =>
      [2] => 2
    )
  [4] => Array
    (
      [0] => 315
      [1] => "Hello World"
      [2] => 2
    )
  [5] => ;
  [6] => Array
    (
      [0] => 370
      [1] =>
      [2] => 2
    )
  [7] => Array
    (
      [0] => 309
      [1] => $a
      [2] => 3
    )
  [8] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [9] => =
  [10] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [11] => Array
    (
      [0] => 305
      [1] => 1
      [2] => 3
    )
  [12] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [13] => +
  [14] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [15] => Array
    (
      [0] => 305
      [1] => 1
      [2] => 3
    )
  [16] => ;
  [17] => Array
    (
      [0] => 370
      [1] =>
      [2] => 3
    )
  [18] => Array
    (
      [0] => 316
      [1] => echo
      [2] => 4
    )
  [19] => Array
    (
      [0] => 370
      [1] =>
      [2] => 4
    )
  [20] => Array
    (
      [0] => 309
      [1] => $a
      [2] => 4
    )
  [21] => ;
  [22] => Array
    (
      [0] => 370
      [1] =>
      [2] => 4
    )
  [23] => Array
    (
      [0] => 369
      [1] => ?>
      [2] => 5
    )
)


各オペランドは次の 2 つの部分で構成されます:

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

b) u、共用体は、op_type に応じて、オペランドの値 (const) または左辺値 (var) を異なる型で格納します。var の場合、各 var は異なります。 IS_TMP_VAR は、名前が示すように、次の op_array で使用するために op_array の結果を保存する一時変数です。このタイプのオペランドの u は、通常、変数テーブルを指すハンドル (整数) を格納します。 used ~ ~0 などの先頭は、変数テーブルの番号 0 にある不明な一時変数 IS_VAR を表します。これは、ZE2.1/ 以降のコンパイラで使用される型を表す IS_CV を表す $ で始まります。 PHP5.1 のキャッシュ メカニズムでは、この変数は、変数が初めて参照されるとき、その変数のアドレスを格納します。この変数へのその後の参照では、アクティブなシンボル テーブルを再度検索する必要はありません。 . CV 変数は ! で始まることで表されます。

$a 変数は !0 に最適化されます。

要約: 上記がこの記事の全内容です。皆様の学習に役立つことを願っています。

関連する推奨事項:

同時実行下でコード取得機能を実装するためにロックを使用する PHP に基づく方法

PHP 自動ローディングの簡単な実装方法

実装された 4 つの基本的な並べ替えアルゴリズムの実行時間の比較PHP で (必読)


以上がPHP の OpCode 原理の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。