今日何人かの友人が、出口と死ぬことには少し違いがあると言いました。 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