PHP の終了と終了について話しましょう

WBOY
リリース: 2016-06-23 13:25:55
オリジナル
1075 人が閲覧しました

今日何人かの友人が、出口と死ぬことには少し違いがあると言いました。 dieって言ったけど、exitの別名じゃないの?私の主張を証明するために、zend_ language_scanner.l の PHP のソース コードを調べてみると、キーワードが同じトークンであることが簡単にわかります:

<ST_IN_SCRIPTING>"exit" {    return T_EXIT;}<ST_IN_SCRIPTING>"die" {    return T_EXIT;}
ログイン後にコピー

つまり、最終的には同じオペコード: ZEND_EXIT です。したがって、これら 2 つのキーワードには違いはなく、実際には言うまでもありません。

友達に注意してもらいたいのですが、整数を出力するために exit を使用しないでください。理由も非常に単純で、PHP 公式 Web サイトのドキュメントで確認できます:

void exit ([string $status] )

void exit (int $status)

If status is文字列。関数は終了する前にステータスを出力します。

status が整数の場合、この値は終了ステータス コードとして使用され、出力されません。 終了ステータス コードは 0 ~ 254 の範囲である必要があり、PHP によって予約されている終了ステータス コード 255 は使用しないでください。 ステータス コード 0 は、プログラムを正常に終了するために使用されます。

そのため、status が整数の場合、印刷ではなくステータス コードとして出力されるため、フロントエンドに返すことはできません。

それでは、このステータス コードは何に使われるのでしょうか?

シェル スクリプトの実行がステータス コードを返す可能性があることは誰もが知っています。PHP スクリプトの実行で返されるステータス コードは同じであり、環境変数でキャプチャできます。

Scholer: ~ $ php -r 'exit(254);'Scholer: ~ $ echo $?254
ログイン後にコピー

私の好奇心が再び呼び起こされました: if 0~255の間ではないですか?テストの結果、ステータス コードが 255 より大きい場合、ステータスは 256 と比較した結果を返すことがわかりました。 0未満の場合、-1~-255の場合はステータス256を加算した結果を返します。-256未満の場合は絶対値と256の余りを返します。つまり、0~255の間です。

探索を続けてください。

exit の実装は zend_vm_def.h にあります:

ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMP|VAR|UNUSED|CV, ANY){#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)    USE_OPLINE    SAVE_OPLINE();    if (OP1_TYPE != IS_UNUSED) {        zend_free_op free_op1;        zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);        if (Z_TYPE_P(ptr) == IS_LONG) {            EG(exit_status) = Z_LVAL_P(ptr);        } else {            zend_print_variable(ptr);        }        FREE_OP1();    }#endif
ログイン後にコピー

コードから、ステータス コードのタイプを検出するために Z_TYPE_P が使用されていることが明確にわかります。それが長い場合は、グローバル変数 exit_status ( EG マクロが使用されています (グローバル変数への便利なアクセス)、そうでない場合は、zend_print_variable を呼び出して出力します。

Z_LVAL_P の宣言は zend_operators.h 内にあります:

#define Z_LVAL_P(zval_p)        Z_LVAL(*zval_p)...#define Z_LVAL(zval)            (zval).value.lval
ログイン後にコピー

次のステップは、誰もが知っている PHP インタープリターでの変数定義です (私のソース コードは PHP7 ではなく、まだ PHP 5.5 バージョンです)。zend.h 内で:

typedef union _zvalue_value {    long lval;                    /* long value */    double dval;                /* double value */    struct {        char *val;        int len;    } str;    HashTable *ht;                /* hash table value */    zend_object_value obj;} zvalue_value;struct _zval_struct {    /* Variable information */    zvalue_value value;        /* value */    zend_uint refcount__gc;    zend_uchar type;    /* active type */    zend_uchar is_ref__gc;};
ログイン後にコピー

したがって、ここでの exit_status の値は依然として長整数です。

それでは、なぜ最終出力ステータス コードが 0 ~ 255 になるのかという疑問が生じます。正直に言うと、私はこの問題を完全には理解していません。これには Linux 環境のプログラミングに精通している必要があります。ここでは簡単に説明することしかできません。

strace を通じて実行をトレースします:

$ strace php -r 'exit(258);' >& strace.log
ログイン後にコピー

結果の最後の 2 行ではっきりとわかります:

...exit_group(258)                         = ?+++ exited with 2 +++
ログイン後にコピー

exit_group の元の値はまだ存在しますが、最終的には 2 になります。 PHP自体はこの値に対して特別な処理を行いませんが、main関数でのexitやreturnでは0~255までの値しか使用できず、それ以外の値は処理されます。簡単なプログラム テストを作成できます:

int main(int argc, char const *argv[]){    return 258;}
ログイン後にコピー

結果:

Scholer: ~ $ ./testScholer: ~ $ echo $?2
ログイン後にコピー

詳細については、以下を参照してください: http://www.laruence.com/2012/02/01/2503.html

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!