PHPのオペコード

WBOY
WBOYオリジナル
2016-06-23 14:37:111067ブラウズ

元のアドレス: http://blog.csdn.net/laruence/archive/2008/07/18/2673488.aspx

Opcode は、Java の ByteCode や NET の MSL と同様に、PHP スクリプトによってコンパイルされる中間言語です。たとえば、次の PHP コードを作成した場合:
echo "Hello World";
$a = 1 + 1;
echo $a;

PHP は、このコードを実行するときに次の 4 つのステップを実行します。 、それは PHP の言語エンジン Zend である必要があります)
1. スキャン (Lexing)、PHP コードを言語フラグメント (トークン) に変換します
2. 解析、トークンを単純で意味のある式に変換します
3. コンパイル、式をオペコードにコンパイルします
4.実行では、オペコードを一度に 1 つずつ順番に実行し、PHP スクリプトの機能を実現します。

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

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

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

Array (
[0] => Array (
[ 0] => 367
) ] => [5 ] => 配列 (
0) => 370 [1] => ; 配列 (
[0 ] => 370
[1] => )

[10] => +

[11] =>
)
( [14] => 配列 (
[0 ] => 370
[1] =>

[16] =>


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

次のステップは解析段階です。解析では、まずトークン配列内の余分なスペースが破棄され、次に残りのトークンが 1 つずつ単純な式に変換されます
1。2 つの数値を加算します
3。 . 前の式の結果を変数に保存します
4. 変数をエコーし​​ます
その後、トークンを 1 つずつ op_array にコンパイルします:

1 。オペコード番号は、add、echo

2 などの各 op_array の操作タイプを示します。 結果 オペコードの結果
3 を格納します。オペランド 1 はオペコード 2
5 のオペランドです。オーバーロードされた演算子

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

* 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、op_type に応じた共用体 違いオペランドの値 (const) または左辺値 (var) が異なる型で保存されることです。 var の場合、各変数は異なります。名前が示すように、これは op_array の一部の結果を保存する一時変数です。次の op_array。このタイプのオペランドの u は、変数テーブルを指すハンドル (整数) を保持します。このタイプのオペランドは、通常、変数テーブル内の 0 を表す ~0 で始まります。

IS_VAR これは、$ で始まる変数です。
IS_CV は、ZE2.1/PHP5.1 以降のコンパイラによって使用されるキャッシュ機構を表します。変数が初めて参照される場合、この変数に対するその後の参照では、アクティブなシンボル テーブルを再度検索する必要はありません。始まりはそれを示しています。

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


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