Comment puis-je obtenir autour de l'absence d'un bloc finally en PHP?
De PHP antérieures à la version 5.5 a pas de bloc finally - c'est à dire, tandis que dans la plupart sensible langues, vous pouvez le faire:
try {
//do something
} catch(Exception ex) {
//handle an error
} finally {
//clean up after yourself
}
PHP a pas la notion d'un bloc finally.
Quelqu'un a une expérience des solutions à ce plutôt irritant trou dans la langue?
finally
a été approuvé, et devrait être disponible dans PHP 5.5. wiki.php.net/rfc/finally- Excellente nouvelle, je peux mettre à jour la question une fois de PHP 5.5 est libéré pour indiquer la disponibilité du bloc finally.
finally
!
Vous devez vous connecter pour publier un commentaire.
Solution, pas. Irritant encombrant solution de contournement, oui:
Dégoûtant, mais devrait fonctionner.
Veuillez noter: PHP 5.5 enfin (ahem, désolé) ajout d'un bloc finally: https://wiki.php.net/rfc/finally (et il n'a fallu que quelques années... disponible dans le 5.5 RC près de quatre ans à la date à depuis que j'ai posté cette réponse...)
if
ne sera pas exécuté.catch (Exception $e) { /* do something */ } if (isset($e)) { /* f finally */ }
catch
bloc de sorte que vous n'avez pas besoin$stored_exc
? Qui fonctionne pour moi, au moins en PHP 5.3.2.La RAII idiome offre un code au niveau de la doublure pour un
finally
bloc. Créer une classe qui détient remboursables(s). Dans le destuctor, appelez le callable(s).Coordination
Noter que PHP n'a pas de bloc de portée de variables, de sorte
Finally
ne seront pas coup de pied jusqu'à ce que la fonction se termine, ou (dans la portée globale) la séquence d'arrêt. Par exemple, les suivantes:entraînera la sortie:
$this
PHP 5.3, les fermetures peuvent pas accéder à
$this
(fixe 5.4), de sorte que vous aurez besoin d'une variable supplémentaire à l'accès les membres de l'instance au sein de certains enfin-blocs.Privé et Protégé Champs
Sans doute le plus gros problème avec cette approche en PHP 5.3 est la enfin-fermeture peuvent pas accès privé et protégé les champs d'un objet. Comme un accès à
$this
, ce problème est résolu dans PHP 5.4. Pour l'instant, privé et immeubles protégés peut être consulté à l'aide de références, comme Artefacto montre dans son réponse à une question sur ce sujet ailleurs sur ce site.Privé et les méthodes protected peut être consulté à l'aide de la réflexion. Vous pouvez en fait utiliser la même technique pour l'accès à la non-public des propriétés, mais les références sont plus simple et plus léger. Dans un commentaire sur le manuel PHP page pour les fonctions anonymes, Martin Partel donne un exemple d'un
FullAccessWrapper
classe qui ouvre la non-public des champs à l'accès public. Je ne vais pas reproduire ici (voir les deux liens ci-dessus pour ça), mais ici, c'est comment vous pouvez l'utiliser:try/finally
try
blocs besoin d'au moins uncatch
. Si vous ne vouleztry/finally
, ajouter uncatch
bloc qui attrape un non-Exception
(code PHP ne peut pas les jeter ce qui n'est pas dérivé deException
) ou de re-jeter l'exception interceptée. Dans le premier cas, je suggère de captureStdClass
comme une expression idiomatique qui signifie "ne pas attraper quoi que ce soit". Dans les méthodes, la capture de la classe actuelle pourrait également être utilisé pour signifier "ne pas attraper quoi que ce soit", mais à l'aide deStdClass
est plus simple et plus facile à trouver lors de la recherche de fichiers.unset $finally
après l'exception d'appel du destructeur tôt.function fooFinally() {}; try { $finally = new Finally(fooFinally); ....
throw new StdClass;
)E_NOTICE
. Lors du passage d'un rappel par nom, utilisez une chaîne de caractères:new Finally('fooFinally')
.Voici ma solution à l'absence de bloc finally. Il permet non seulement de contourner le bloc finally, il étend également le try/catch pour attraper les erreurs PHP (et les erreurs fatales trop). Ma solution ressemble à ceci (PHP 5.3):
Vous pouvez télécharger la solution avec de la documentation et des exemples de git hub -
https://github.com/Perennials/travelsdk-core-php/tree/master/src/sys
Que c'est une construction du langage, vous ne trouverez pas une solution simple pour cela.
Vous pouvez écrire une fonction et l'appeler comme la dernière ligne de votre bloc try et de la dernière ligne avant le renvoi de l'excepion dans le bloc try.
De bons livres s'oppose enfin à l'aide de blocs pour tout autre que de libérer des ressources que vous ne pouvez pas être sûr qu'il va exécuter si quelque chose de désagréable se produit. En appelant un irritant trou est tout à fait exagéré.
Croyez-moi, un enfer beaucoup de exceptionnellement bon code est écrit dans des langues sans bloc finally. 🙂
Le point de enfin est de l'exécuter, peu importe si le bloc try a été réussie ou non.
Appel à l'aide de fermetures. Deuxième paramètre,
$catch
, est facultative. Exemples:Gère correctement les exceptions partout:
$try
: Exception sera transmis à$catch
.$catch
sera exécuté en premier, puis$finally
. Si il n'y a pas de$catch
, exception seront relancés après l'exécution de$finally
.$catch
:$finally
exécutera immédiatement. Exception sera renvoyé après$finally
complète.$finally
: Exception pause en bas de la pile des appels sans entrave. Toutes les autres exceptions prévues pour renvoyer seront rejetées.$try
sera retourné.Si quelqu'un est encore de garder la trace de cette question, vous pourriez être intéressé à vérifier le (tout nouveau) RFC pour une enfin pour le langage dans le PHP wiki. L'auteur semble déjà avoir travaillé avec des patchs, et je suis sûr que la proposition permettrait de bénéficier d'autres développeurs de la rétroaction.
Je viens de terminer l'écriture d'un plus élégant Try Catch Enfin de classe qui peuvent vous être utiles. Il y a quelques inconvénients, mais ils peuvent être contournées.
https://gist.github.com/Zeronights/5518445