今天有小伙伴说 exit 和 die 有一点差别。我说 die 不就是 exit 的别名吗?为了证明我的观点,翻了翻 PHP 的源码,在 zend_language_scanner.l 中,很容易就能发现这关键字是同一个 token:
<ST_IN_SCRIPTING>"exit" { return T_EXIT;}<ST_IN_SCRIPTING>"die" { return T_EXIT;}
所以最终也是同一个 Opcode:ZEND_EXIT。所以这两个关键字没有任何差别,这其实也没什么好说的。
我顺便提醒了小伙伴们一句:不要用 exit 输出整数。原因也很简单,在 PHP 官网的文档里就能看到:
void exit ([ string $status ] )
void exit ( int $status )
如果 status 是一个字符串,在退出之前该函数会打印 status 。
如果 status 是一个 integer,该值会作为退出状态码,并且不会被打印输出。 退出状态码应该在范围0至254,不应使用被PHP保留的退出状态码255。 状态码0用于成功中止程序。
所以如果 status 是一个整数,会被当成状态码输出,而不是打印,所以如果想返回给前端是不可能的。
那么这个状态码有什么用呢?
大家都知道 shell 脚本执行可以返回一个状态码,PHP 的脚本的执行返回的状态码是一样的,可以在环境变量中被捕捉到:
Scholer: ~ $ php -r 'exit(254);'Scholer: ~ $ echo $?254
我的好奇心又被勾起来了:如果给的是不在 0 ~ 255 之间的状态码会怎么样呢?经过测试,发现如果是大于 255 的状态码,会返回 status 对 256 求于之后的结果。如果是小于 0 的,在 -1 ~ - 255 之间时返回的是 status 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 来检测状态码的类型,如果是 long 的话就赋值给全局变量 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 解释器中的变量定义了(我这份源码还是 PHP 5.5 的版本,不是 PHP7),在 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
在结果的最后两行可以很清楚的看到:
...exit_group(258) = ?+++ exited with 2 +++
exit_group 中还是原始值,但最终会变成 2 。PHP 本身并没有对这个值做特殊处理,但是 exit 或者 main 函数中的 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主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP在現代化進程中仍然重要,因為它支持大量網站和應用,並通過框架適應開發需求。 1.PHP7提升了性能並引入了新功能。 2.現代框架如Laravel、Symfony和CodeIgniter簡化開發,提高代碼質量。 3.性能優化和最佳實踐進一步提升應用效率。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP中使用clone關鍵字創建對象副本,並通過\_\_clone魔法方法定制克隆行為。 1.使用clone關鍵字進行淺拷貝,克隆對象的屬性但不克隆對象屬性內的對象。 2.通過\_\_clone方法可以深拷貝嵌套對象,避免淺拷貝問題。 3.注意避免克隆中的循環引用和性能問題,優化克隆操作以提高效率。

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具