2010-10-11 2 views
0

Il ya beaucoup de fonctions (en fait, les plus) dans le langage PHP qui se fâchent et émettent des avertissements et des avis quand ils n'aiment pas leur entrée - plutôt que de simplement revenir FALSE (mais ils le font aussi).PHP alternatives à la gestion des entrées malformées au lieu de lancer des erreurs

Un endroit où cela est vraiment commun est dans les fonctions GD et chaîne. Ils sont très pointus sur leurs arguments et il est très facile pour les utilisateurs de ne pas respecter leurs standards.

Par exemple, un utilisateur télécharge une image endommagée (intentionnellement ou non). Résultant des avertissements de la bibliothèque GD.

Jusqu'à présent, il n'y a que trois façons que j'ai trouvé au silence PHP sur cette question:

  • Changer votre établissement de rapports d'erreur dans le ini ou at runtime (beurk). Supprimer les erreurs avec le symbole @ lent.
  • Modifier erreur de déclaration juste avant/après la fonction:

comme ceci:

$errorlevel=error_reporting(); 
error_reporting($errorlevel & ~E_NOTICE); 
//...code that generates notices 
error_reporting($errorlevel); 

Naturellement, les deux deuxièmes choix me rendent malade. Ce qui me laisse utiliser 1) et atténuer les paramètres d'erreur PHP. Cependant, je veux que PHP soit en mode strict afin que, pendant que je travaille, je puisse attraper des bogues logiques et une mauvaise forme qui pourrait s'introduire dans mon code. Cependant, je ne veux pas que des erreurs aléatoires soient lancées quand PHP n'aime pas quelque chose.

Y a-t-il un moyen de séparer les erreurs provenant d'arguments malformés (mauvaise entrée) des erreurs de mauvaise programmation? Par exemple:

  1. Si une image utilisateur est invalide juste retour FALSE et je vais faire face. Je n'ai pas besoin d'avertissements.
  2. Si le passage d'une ressource d'image à la fonction d'impression est invalide, jetez des avertissements.
+0

Toutes les fonctions GD imagecreate * doivent déjà renvoyer false en cas d'erreur ou utilisez-vous autre chose? – tadamson

+0

@tadamson Beaucoup de fonctions GD jettent aussi un avertissement/notification en plus de renvoyer false: http://us.php.net/manual/fr/function.getimagesize.php – leepowers

+0

@tadamson Comme je l'ai mentionné plus haut, elles retournent FALSE. Cependant, ils lancent aussi E_WARNINGS qui ne peut pas être attrapé juste là et analysé comme une exception ou un résultat booléen. – Xeoncross

Répondre

1

corriger le code

Désinfectez l'entrée avant que vous appelez les fonctions. Cela vous évite des erreurs.

+1

Je ne suis pas au courant d'un moyen de jauger si un fichier image est valide jusqu'à ce que je tente de l'ouvrir avec GD. Si GD ne peut pas le lire * alors je sais que c'est invalide *. – Xeoncross

+0

Xeoncross, dans ce cas, des exceptions sont nécessaires. Bien sûr, PHP ne vous aidera pas nativement. – erisco

0

S'il y a quelque chose comme ça, vous pouvez utiliser les @-operator

ne est pas une solution __gVirt_NP_NN_NNPS<__ propre, mais il y a des situations où il est indispensable.

Avez-vous vérifié l'image avant d'utiliser getimagesize()?

3

Il existe une autre alternative - utilisez set_error_handler(), vous pouvez même l'appeler juste avant l'appel de la fonction GD et revenir à la valeur par défaut avec restore_error_handler().

Il y a un bon commentaire dans la question try and catch a warning qui donne plus de détails sur comment cela est accompli.

+0

Oui, j'ai effectivement * utilisé * pour le faire. Cependant, ajouter un bloc try {} catch {} pour chaque fonction augmenterait considérablement la taille de la base de code. Chaque 1 ligne fonctionne maintenant = 5 lignes de code. De plus, cela ralentit considérablement le code car la gestion des exceptions prend plus de temps que la simple vérification de '$ result === FALSE' – Xeoncross

+0

Vous n'avez pas besoin d'utiliser try/catch pour chaque fonction, vous pouvez utiliser' add_exception_handler() 'pour définir un gestionnaire par défaut pour toutes les exceptions. –

+0

Mais si j'installe un gestionnaire global alors comment est-ce que je rattache cela au code que je courais quand c'est arrivé? Je dois attraper l'exception juste là pour y faire face - ou bien maquiller un système d'événements encombrant qui fait la même chose. – Xeoncross

2

Ceci est un mauvais design depuis les débuts de PHP. Une bibliothèque PHP moderne lancerait une exception en cas d'erreur. Et une exception peut être interceptée. Mais à l'époque, GD était écrit que PHP ne supportait pas encore les exceptions.

Ainsi, je pense que dans ce cas est légitime d'utiliser l'opérateur @.

+0

Lancer des exceptions serait aussi bien avec moi puisque je peux les manipuler de la même manière que je le ferais pour une vérification FALSE booléenne sur le résultat de la fonction. Pour le mal il ne jette pas quelque chose qui est attrapable ... – Xeoncross

0

Cependant, je ne veux pas avoir des erreurs aléatoires lancées lorsque PHP n'aime pas quelque chose.

Pourquoi pas? PHP essaie de vous dire quelque chose de notable avec des avertissements et des avis. Dans l'exemple GD, vous devez vous connecter lorsqu'un utilisateur télécharge un fichier corrompu, en particulier s'il est utilisé dans une attaque. Turn of the display of error messages and log everything.

+0

Je pense que le plus gros problème de ne pas attraper les erreurs est que l'utilisateur est jeté à un écran blanc ou partiellement chargé sans explication claire sur ce qui s'est mal passé ou ce qui se passe . Pour un utilisateur moyen, cela serait assez troublant. – Dandy

+0

Cela ne devrait pas être un problème car les fonctions retournent également false, que vous pouvez détecter et afficher quelque chose d'autre qu'une page vierge.Les avertissements ne tuent pas l'exécution de votre script et vous ne devriez pas les sortir sur un serveur de production. – Klinky

+0

Oui, il n'est pas nécessaire de lancer des erreurs d'avertissement si vous vérifiez que la sortie d'une fonction GD sur une image utilisateur est '=== FALSE'. À ce stade, vous devez savoir que quelque chose ne va pas et enregistrer vous-même les données sur la situation. – Xeoncross

1

Il n'y a pas d'approche générique pour toutes les bibliothèques en dehors de l'édition de la bibliothèque fautive et de la manière dont elle génère des exceptions. Honeslty, beaucoup de développeurs PHP ne se sont pas souciés des exceptions lancées, mais maintenant de plus en plus de gens arrivent sur le wagon E_STRICT. Quand les libs de GD ont été générées, la mentalité était probablement que lancer des erreurs insaisissables n'était pas un gros problème.

En ce qui concerne la validation des images avec GD. La seule chose que vous pouvez vraiment faire est d'utiliser une bibliothèque ou une fonction différente pour valider vos images. Vous pouvez try using magic byte functions vérifier si les images ont des en-têtes appropriés (bien que cela ne signifie pas que le reste du fichier est structuré correctement). Au moins, en utilisant les fonctions d'octets magiques, vous vous occuperez de choses évidentes comme quelqu'un qui télécharge un fichier texte au lieu d'un fichier JPEG.

+0

Peut-être que je suis juste en train de réaliser un choix de conception qui, je l'espère, va changer à mesure que PHP se déplace dans un monde basé sur des objets plus lourds. Cependant, j'espérais qu'il y aurait eu une meilleure solution temporaire pour le moment. – Xeoncross