Let's talk about PHP's die and exit. Today, some friends say there is a difference between exit and die. Do I say that die is not the alias of exit? To prove my point of view, I flipped through the PHP source code. in zend_language_scanner.l, it is easy to find that this keyword is the same token:
"exit" { return T_EXIT;}
"die" { return T_EXIT;}
Therefore, it is also the same Opcode: ZEND_EXIT. So there is no difference between the two keywords, which is actually nothing to say.
By the way, I reminded my friends: Do not use exit to output integers. The reason is also very simple. you can see it in the document on the PHP official website:
VoidExit([String $ status])
VoidExit(Int $ status)
If status is a string, the function prints status before exiting.
If status is an integer, the value is used as the exit status code and will not be printed. The exit status code ranges from 0 to 254. the exit status code 255 retained by PHP should not be used. Status Code 0 is used to successfully stop the program.
Therefore, if status is an integer, it will be output as a status code rather than printed. Therefore, it is impossible to return it to the front-end.
So what is the purpose of this status code?
As we all know, a status code can be returned for shell script execution. the status code returned by PHP script execution is the same and can be captured in environment variables:
Scholer: ~ $ php -r 'exit(254);'Scholer: ~ $ echo $?254
My curiosity is aroused again: if it is not 0 ~ What will happen to the status code between 255? After testing, it is found that if it is a status code greater than 255, it will return the result after the status is 256. If it is less than 0, in-1 ~ The result of the sum of status 255 is returned when the value is between-256. if the value is less than-256, it is the absolute value and the remainder of 256. In a word, they are all 0 ~ In the range of 255.
Go on to explore.
Exit is implemented in 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
From the code, we can clearly see that the type of status code is checked through Z_TYPE_P, if it is long, assign the value to the global variable exit_status (the macro EG is used to conveniently access the global variable). If not, call zend_print_variable to print it out.
The declaration of Z_LVAL_P is in zend_operators.h:
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)...#define Z_LVAL(zval) (zval).value.lval
Further, we all know that the variables in the PHP interpreter are defined (this is my source code or PHP 5.5, not PHP7). In 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;};
Therefore, the value of exit_status is still a long integer.
Then the question arises, why is the final output 0 ~ What is the status code between 255? To be honest, I am not very familiar with this problem, so I need to be familiar with programming in the Linux environment.
Use strace to trace and execute:
$ strace php -r 'exit(258);' >& strace.log
In the last two rows of the result, we can clearly see that:
...exit_group(258) = ?+++ exited with 2 +++
Exit_group is still the original value, but it will eventually become 2. PHP does not perform special processing on this value, but the return in exit or main function can only use 0 ~ Values between 255 and other values are processed. You can write a simple program for testing:
int main(int argc, char const *argv[]){ return 258;}
Result:
Scholer: ~ $ ./testScholer: ~ $ echo $?2
See http://www.laruence.com/2012/02/01/2503.html for details