最近、PHPでempty関数とisset関数を使うときの変数の判定方法について質問されましたが、少ししか知らなかったので最初は戸惑いました。その真の原理を理解して、すぐにソースコードを開いて調べてください。分析すると、両方の関数が同じ関数を呼び出していることがわかります。この記事では、2 つの関数をまとめて分析します。
github の PHP ソース コードにさらに詳細な注釈を付けています。興味があれば、見てスターを付けてください。 PHP5.4のソースコードのアノテーション。追加された注釈は、コミット レコードを通じて表示できます。
変数が空かどうかを判断します。
変数が設定されているか、NULL ではないかを確認してください。
PHP5.5 より前では、空の変数パラメータのみがサポートされていました。たとえば、関数呼び出しの結果は解析エラーの原因となります。
isset の場合、unset などの関数で変数が NULL に設定されている場合、関数は false を返します。複数のパラメータが isset 関数に渡された場合、isset 関数はすべてのパラメータが設定されている場合にのみ true を返します。左から右に計算し、設定されていない変数が見つかるとすぐに停止します。
実際には、empty は関数ではなく、言語構造です。言語構造は PHP プログラムが実行される前にコンパイルされるため、以前のように単に「PHP_FUNCTION empty」または「ZEND_FUNCTION empty」を検索してソース コードを表示することはできません。 emptyなどの言語構造のソースコードを見たい場合は、まずPHPコード実行の仕組みを理解する必要があります。
PHP の実行コードは 4 つのステップを経て、フローチャートは次のとおりです:
次に、解析段階に入ります。この段階では、プログラムは T_ISSET や T_EMPTY などのトークンを意味のある式に変換します。このとき、トークンの yacc が zend_lang_parser.y ファイルに保存されます。 T_EMPTY が見つかります:
isset 関数と empty 関数は、最終的に zend_do_isset_or_isempty 関数を実行します。
grep -rn "zend_do_isset_or_isempty" の検索を続けてください。この関数は zend_compile.c ファイルで定義されていることがわかります。
関数の実行手順
2. 書き込み可能な変数かどうかを確認します
3. 変数の op_type が IS_CV (コンパイル時変数) の場合は、そのオペコードを ZEND_ISSET_ISEMPTY_VAR に設定します。それ以外の場合は、active_op_array から次の op 値を取得し、その op 値に従って last_op のオペコードを設定します。
4. オペコードを設定した後、実行のために zend_excute に渡されます。
空の関数については、オペコードステップに到達した後、isset および empty が実行時に
ZEND_ISSET_ISEMPTY_VAR などの一連の関数を実行することがわかります。この関数の定義は zend_vm_execute.h にあります。関数を見ると、空の関数の最終実行関数は i_zend_is_true(), であり、i_zend_is_true 関数は zend_execute.h で定義されていることがわかります。 i_zend_is_true 関数のコアコードは次のとおりです: リーリー このコードは比較的直感的です。このコードを使用して、例の空の関数をさらに分析します:
empty(null)、IS_NULL 分岐に移動、result=0、i_zend_is_true。 () == 0、!i_zend_is_true() == 1 なので、true を返します。
empty(false)、IS_BOOL 分岐へ、result = ZLVAL_P(false) = 0、i_zend_is_true() == 0、!i_zend_is_true() == 1 なので、true が返されます。
empty('0')、IS_STRING 分岐へ。Z_STRLENP(op) == 1 および Z_STRVAL_P(op)[0] == '0' であるため、結果は 0、i_zend_is_true() == 0、!i_zend_is_true () == 1 なので、true を返します。
empty(1)、IS_LONG 分岐へ、result = Z_LVAL_P(op) = 1、i_zend_is_true == 1、!i_zend_is_true() == 0 なので false が返されます。
isset 関数の場合、判定を実装する最終コードは次のとおりです:
リーリー
値が設定されており、NULL でない限り、isset 関数は true を返します。
まとめ
今回これら 2 つの関数のソースコードを読んで、次のことがわかりました:
2. PHP言語構造のソースコードの場所を見つける方法
3. オペコード処理関数の特定の関数を見つける方法
学習に終わりはありません。誰もが自分の欠点を持っています。継続的に学習することによってのみ、私たちは自分の欠点を補うことができます。
限られた文体と限られた知識によるオリジナル記事 記事内に何か間違っている点がございましたら、お知らせください。
この記事がお役に立ちましたら、クリックしておすすめしてください、ありがとうございます^_^
最後に、おまけとして、github の PHP ソース コードにさらに詳細な注釈を付けました。興味があれば、見てスターを付けてください。 PHP5.4のソースコードのアノテーション。追加されたアノテーションは、コミット レコードを通じて確認できます。
参考記事
オペコード処理関数の検索: http://www.laruence.com/2008/06/18/221.html
PHPopcode と PHP コードの実行手順の詳細: http://www.php- Internals.com /book/?p=chapt02/02-03-03-from-opcode-to-handler
その他のソース コード記事については、個人のホームページにアクセスして閲覧を続けてください: hoohack
。