Maison développement back-end tutoriel php 说说 PHP 的 die 和 exit

说说 PHP 的 die 和 exit

Jun 23, 2016 pm 01:25 PM

今天有小伙伴说 exit 和 die 有一点差别。我说 die 不就是 exit 的别名吗?为了证明我的观点,翻了翻 PHP 的源码,在 zend_language_scanner.l 中,很容易就能发现这关键字是同一个 token:

<ST_IN_SCRIPTING>"exit" {    return T_EXIT;}<ST_IN_SCRIPTING>"die" {    return T_EXIT;}
Copier après la connexion

所以最终也是同一个 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
Copier après la connexion

我的好奇心又被勾起来了:如果给的是不在 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
Copier après la connexion

从代码中我们可以很明显的看出来通过 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
Copier après la connexion

再进一步就是大家都知道的 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;};
Copier après la connexion

所以这里 exit_status 的值到这里还是一个长整形。

那么问题就来了,为什么最终输出的是 0 ~ 255 之间的状态码呢?老实说这个问题我吃的也不是很透,这需要对 Linux 环境编程足够熟悉才行,这里只能简单的说一下。

通过 strace 跟踪一下执行:

$ strace php -r 'exit(258);' >& strace.log
Copier après la connexion

在结果的最后两行可以很清楚的看到:

...exit_group(258)                         = ?+++ exited with 2 +++
Copier après la connexion

exit_group 中还是原始值,但最终会变成 2 。PHP 本身并没有对这个值做特殊处理,但是 exit 或者 main 函数中的 return,只能使用 0 ~ 255 之间的值,其他值都会被处理。可以写一个简单的程序测试:

int main(int argc, char const *argv[]){    return 258;}
Copier après la connexion

结果:

Scholer: ~ $ ./testScholer: ~ $ echo $?2
Copier après la connexion

详情参见:http://www.laruence.com/2012/02/01/2503.html

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Apr 05, 2025 am 12:04 AM

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Comment fonctionne le détournement de session et comment pouvez-vous l'atténuer en PHP? Comment fonctionne le détournement de session et comment pouvez-vous l'atténuer en PHP? Apr 06, 2025 am 12:02 AM

Le détournement de la session peut être réalisé via les étapes suivantes: 1. Obtenez l'ID de session, 2. Utilisez l'ID de session, 3. Gardez la session active. Les méthodes pour empêcher le détournement de la session en PHP incluent: 1. Utilisez la fonction Session_RegeReate_id () pour régénérer l'ID de session, 2. Stocker les données de session via la base de données, 3. Assurez-vous que toutes les données de session sont transmises via HTTPS.

Décrivez les principes solides et comment ils s'appliquent au développement de PHP. Décrivez les principes solides et comment ils s'appliquent au développement de PHP. Apr 03, 2025 am 12:04 AM

L'application du principe solide dans le développement de PHP comprend: 1. Principe de responsabilité unique (SRP): Chaque classe n'est responsable d'une seule fonction. 2. Principe ouvert et ferme (OCP): les changements sont réalisés par extension plutôt que par modification. 3. Principe de substitution de Lisch (LSP): les sous-classes peuvent remplacer les classes de base sans affecter la précision du programme. 4. Principe d'isolement d'interface (ISP): utilisez des interfaces à grain fin pour éviter les dépendances et les méthodes inutilisées. 5. Principe d'inversion de dépendance (DIP): les modules élevés et de bas niveau reposent sur l'abstraction et sont mis en œuvre par injection de dépendance.

Comment définir automatiquement les autorisations d'UnixSocket après le redémarrage du système? Comment définir automatiquement les autorisations d'UnixSocket après le redémarrage du système? Mar 31, 2025 pm 11:54 PM

Comment définir automatiquement les autorisations d'UnixSocket après le redémarrage du système. Chaque fois que le système redémarre, nous devons exécuter la commande suivante pour modifier les autorisations d'UnixSocket: sudo ...

Comment déboguer le mode CLI dans phpstorm? Comment déboguer le mode CLI dans phpstorm? Apr 01, 2025 pm 02:57 PM

Comment déboguer le mode CLI dans phpstorm? Lors du développement avec PHPStorm, nous devons parfois déboguer PHP en mode interface de ligne de commande (CLI) ...

Expliquez la liaison statique tardive en PHP (statique: :). Expliquez la liaison statique tardive en PHP (statique: :). Apr 03, 2025 am 12:04 AM

Liaison statique (statique: :) ​​implémente la liaison statique tardive (LSB) dans PHP, permettant à des classes d'appel d'être référencées dans des contextes statiques plutôt que de définir des classes. 1) Le processus d'analyse est effectué au moment de l'exécution, 2) Recherchez la classe d'appel dans la relation de succession, 3) il peut apporter des frais généraux de performance.

Comment envoyer une demande post contenant des données JSON à l'aide de la bibliothèque Curl de PHP? Comment envoyer une demande post contenant des données JSON à l'aide de la bibliothèque Curl de PHP? Apr 01, 2025 pm 03:12 PM

Envoyant des données JSON à l'aide de la bibliothèque Curl de PHP dans le développement de PHP, il est souvent nécessaire d'interagir avec les API externes. L'une des façons courantes consiste à utiliser la bibliothèque Curl pour envoyer le post� ...

See all articles