J'ai l'intention de vous donner une discussion des plus inhabituelles sur le contrôle des erreurs.
J'ai construit un très bon gestionnaire d'erreurs dans un langage il y a des années, et bien que certains des noms aient changé, les principes du traitement des erreurs sont les mêmes aujourd'hui. J'avais un système d'exploitation multi-tâches personnalisé et je devais être en mesure de récupérer des erreurs de données à tous les niveaux sans fuites de mémoire, croissance de la pile ou plantages. Ce qui suit est donc ma compréhension de la manière dont les erreurs et les exceptions doivent fonctionner et en quoi elles diffèrent. Je dirai simplement que je ne comprends pas comment les composants internes de try catch fonctionnent, donc je suppose dans une certaine mesure.
La première chose qui se passe sous les couvertures du traitement des erreurs est de passer d'un état de programme à un autre. Comment cela se fait-il? J'y reviendrai.
Historiquement, les erreurs sont plus anciennes et plus simples, et les exceptions sont plus récentes et un peu plus complexes et capables. Les erreurs fonctionnent bien jusqu'à ce que vous ayez besoin de les faire remonter, ce qui équivaut à confier un problème difficile à votre superviseur.
Les erreurs peuvent être des nombres, comme des numéros d'erreur, et parfois avec une ou plusieurs chaînes associées. Par exemple, si une erreur de lecture de fichier se produit, vous pourrez peut-être signaler ce que c'est et éventuellement échouer correctement. (Hay, c'est un pas en avant par rapport au crash comme autrefois.)
Ce qui n'est pas souvent dit à propos des exceptions, c'est que les exceptions sont des objets superposés sur une pile d'exceptions spéciale. C'est comme une pile de retour pour le flux du programme, mais elle contient un état de retour uniquement pour les essais et les captures d'erreur. (J'avais l'habitude de les appeler ePush et ePop, et? Abort était un lancer conditionnel qui ePop et récupérait à ce niveau, tandis que Abort était un dé complet ou une sortie.)
Au bas de la pile se trouvent les informations sur l'appelant initial, l'objet qui connaît l'état lorsque l'essai externe a été lancé, ce qui correspond souvent au démarrage de votre programme. En plus de cela, ou la couche suivante de la pile, avec up étant les enfants et down étant les parents, se trouve l'objet d'exception du prochain bloc try / catch interne.
Si vous faites un essai à l'intérieur d'un essai, vous empilez l'essai intérieur au-dessus de l'essai extérieur. Lorsqu'une erreur se produit dans l'essai interne et que soit le catch interne ne peut pas le gérer, soit l'erreur est renvoyée à l'essai externe, le contrôle est passé au bloc catch externe (objet) pour voir s'il peut gérer l'erreur, c'est-à-dire votre superviseur.
Donc, ce que cette pile d'erreurs fait vraiment est de pouvoir marquer et restaurer le flux du programme et l'état du système, en d'autres termes, elle permet à un programme de ne pas planter la pile de retour et de gâcher les choses pour les autres (données) lorsque les choses tournent mal. Ainsi, il enregistre également l'état de toutes les autres ressources telles que les pools d'allocation de mémoire et peut donc les nettoyer lorsque la capture est terminée. En général, cela peut être une chose très compliquée, et c'est pourquoi la gestion des exceptions est souvent lente. En général, un peu d'état doit entrer dans ces blocs d'exceptions.
Donc, une sorte de bloc try / catch définit un état auquel il est possible de revenir si tout le reste est gâché. C'est comme un parent. Quand nos vies sont gâchées, nous pouvons retomber sur les genoux de nos parents et ils le feront à nouveau.
J'espère que je ne vous ai pas déçu.
Errors are generally unrecoverable
<- en fait, ce n'est pas vraiment vrai.E_ERROR
etE_PARSE
sont les deux erreurs irrécupérables les plus courantes (il y en a quelques autres) mais la grande majorité des erreurs que vous verrez dans le développement sont récupérables (E_NOTICE
,E_WARNING
et al). Malheureusement, la gestion des erreurs de PHP est un désordre complet - toutes sortes de choses déclenchent des erreurs inutilement (la grande majorité des fonctions du système de fichiers, par exemple). En général, les exceptions sont "la manière OOP", mais malheureusement certaines des API natives de PHP utilisent des erreurs au lieu d'exceptions :-(