Maison > Article > développement back-end > PHP 7.4 permet de lever des exceptions depuis __toString()
PHP 7.4 autorise les exceptions de __toString()
Introduction
Actuellement interdit de __toString() lève une exception et provoquera une erreur fatale erreur. Cela rend l’appel de code arbitraire dangereux et en fait une API à usage général problématique. Cette RFC vise à supprimer cette restriction.
La raison du comportement actuel est que les conversions de chaînes sont effectuées à de nombreux endroits dans le moteur et la bibliothèque standard, et ne sont pas partout prêtes à gérer les exceptions "correctement", c'est-à-dire le plus tôt possible.
D'un point de vue technique, cette restriction est finalement invalide, puisque des exceptions lors de la conversion de chaîne peuvent toujours être déclenchées par des gestionnaires d'erreurs qui convertissent les erreurs récupérables en exceptions :
set_error_handler(function() { throw new Exception(); }); try { (string) new stdClass; } catch (Exception $e) { echo "(string) threw an exception...\n"; }
En fait, Symfony exploite cette vulnérabilité pour contourner les restrictions actuelles. Malheureusement, cela repose sur le paramètre $errcontext, qui a disparu dans PHP 8.
Cependant, jusqu'à ce que nous fassions un examen complet des conversions de chaînes dans cette base de code, les articles précédents sur ce sujet n'ont pas discuté de l'assouplissement de ce paramètre. restriction. Cela a été fait dans une demande de mise en œuvre ci-jointe.
Il est recommandé que
autorise la levée d'exceptions depuis __toString() et cela se comporte comme d'habitude. Les erreurs fatales ne sont plus déclenchées.
De plus, conversion des erreurs fatales récupérables "ne peut pas être converti en chaîne" et "__toString() doit renvoyer une valeur de chaîne" en exceptions d'erreur correctes, conformément à la politique d'erreur établie dans PHP 7.
Consignes d'extension
Les auteurs d'extensions qui souhaitent gérer les exceptions des conversions de chaînes avec élégance doivent prendre en compte les directives suivantes :
● Si zval_get_string( ), convert_to_string () et les amis génèrent une exception, ils génèrent toujours une chaîne. Cette chaîne est garantie comme étant temporaire. Cela signifie qu’il n’est pas nécessaire de le libérer, mais que cela est possible. Dans le contexte, vous pouvez choisir l'option la plus pratique.
● Le résultat de la conversion de chaîne sera une chaîne vide si la conversion d'objet en chaîne échoue, ou une chaîne vide si le tableau est converti en chaîne et que le gestionnaire d'erreurs élève la notification de résultat à une exception . "Tableau". (Le comportement est le même qu'avant.)
● Habituellement, il suffit de vérifier si une exception a été levée en utilisant la vérification habituelle if (EG(exception)) :
zend_string *str = zval_get_string(val); if (EG(exception)) { // Possibly free other resources here. return; }
sauf en plus , certaines API d'assistance sont fournies pour modéliser les conversions comme des opérations sujettes aux erreurs :
// Like zval_get_string() but returns NULL on conversion failure. zend_string *str = zval_try_get_string(val); if (!str) { // Possibly free other resources here. return; } // Main code. zend_string_release(str); // Like zval_get_tmp_string() but returns NULL on conversion failure. zend_string *tmp, *str = zval_try_get_tmp_string(val, &tmp); if (!str) { // Possibly free other resources here. return; } // Main code. zend_tmp_string_release(tmp); // Like convert_to_string() but returns a boolean indicating conversion success/failure. if (!try_convert_to_string(val)) { // Possibly free other resources here. return; } // Main code.
Si la conversion échoue, try_convert_to_string() ne modifiera pas la valeur d'origine. Par conséquent, son utilisation est plus sûre que l’utilisation de convert_to_string() et la vérification des exceptions.
Bien que vérifier chaque conversion de chaîne vous mettra certainement du bon côté, ignorer ces vérifications n'entraîne souvent que quelques calculs inutiles et éventuellement des avertissements redondants. La principale chose à laquelle vous devez prêter attention sont les opérations qui modifient les structures persistantes (telles que les bases de données).
Modifications rétrocompatibles
La transition d'une erreur fatale récupérable à une exception d'erreur est techniquement une rupture de BC.
Traduction : https://wiki.php.net/rfc/tostring_exceptions
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!