10
votes

Limiter le gestionnaire d'erreur PHP à des espaces de noms spécifiques

Y a-t-il une manière dans PHP pour définir un gestionnaire d'erreur uniquement pour des espaces de noms spécifiques? Je construis un petit cadre et je voudrais pouvoir essayer tous les messages d'erreur / d'avertissement / remarquez dans son espace de noms en définissant le gestionnaire d'erreur personnalisé et en jetant des exceptions avec elle. Les erreurs déclenchées en dehors de cet espace de noms spécifique devraient se comporter de manière régulière.

peut-il être fait avec PHP?

merci.


1 commentaires

Je ne pense pas: il n'y a pas d'informations sur l'espace de noms dans les données de retour de débog_backtrace () (sur la base duquel vous pouvez indiquer à votre gestionnaire d'erreur comment réagir). Intéressé à voir si quelque chose se présente.


3 Réponses :


0
votes

peut-il être fait avec PHP?

Cela peut être fait assez facilement, je dirais. Sans réellement écrire le code, c'est ce que je ferais:

  1. Créez un bloc d'essai / attraper
  2. attrape toutes les exceptions ( \ exception )
  3. Trouvez la dernière classe appelée (quelque part dans $ exception-> gettrace () )
  4. Cette classe aura son espace de noms dans son nom: quelque \ nom \ espace \ classe
  5. Utilisez dirname ($ espace de noms) pour supprimer le nom de la classe ( "classe" dans ce cas)
  6. Faites ce que vous aimez avec le résultat ou réthrow l'exception: lancer une exception;

    edit
    Même les fermetures ont des espaces de noms: xxx

    $ ex> gettrace () [0] ['fonction'] sera oele \ boele \ {fermeture}

    edit
    Dommage que le tableau Trace ne dispose pas d'une clé '"espace de noms" pour chaque élément.


5 commentaires

Je pense que l'OP a posé des questions sur Set_error_handler () , pour ne pas avoir à tout emballer dans des blocs géants Essayer / Catch


Si c'est un cadre, la majeure partie de celle-ci "devrait" être enveloppée dans un grand bloc d'essai / attraper dans le frontController de toute façon ... imo


Oui, je pensais plutôt à Set_error_handler (). Attraper votre propre exception personnalisée ne devrait pas être un problème Idneed.


Omg c'est une si mauvaise réponse ... Premier que l'OP ne parlait pas d'essayer / attraper des blocs. Deuxièmement, l'utilisation de BackTrace ... Troisième, à l'aide de DirName sur un nom de classe FQ est juste mal. Enfin, quand vous commencez par "C'est juste une question idiote!", Assurez-vous que ce n'est pas juste une réponse idiote!


Il ne parlait pas d'essayer / attraper ... il demandait une solution. Habituellement, cela n'inclut pas la réponse. Quel est le problème avec la backtrace? Ça marche!? Pourquoi utiliser le dirname faux? Ça marche! Il a demandé si c'est possible. Il est. Ce n'est pas une bonne solution, mais c'est une réponse (et, ai-je dit: ça marche!)



1
votes

Je n'ai pas essayé de faire cela avant, alors je m'excuse à l'avance si cela ne fonctionne pas (à tout le moins, cela peut vous faire penser), mais c'est ainsi que j'essaierais de l'accomplir:

Étant donné que votre espace de noms se séparer d'un cadre global plus grand, je disposerais de toutes les classes dans le cadre d'étendre une classe de base (pour cela permet de l'appeler la base de la base). À l'intérieur de cette classe, je créerais une méthode appelée errorHandler (). À l'intérieur de cette fonction, vous feriez tout ce que vous voulez faire pour votre manipulation d'exception (peut-être même jetant une exception vous-même).

Maintenant que vous avez cette fonctionnalité, nous devons déterminer comment obtenir cette fonction appelée. Étant donné que tous les objets de votre espace de noms étendent la base de base, ils ont tous accès à cette méthode d'erreur (). Maintenant, à l'intérieur de votre code, vous pouvez utiliser les blocs Essaye / Catch normaux pour capturer des exceptions qui se produisent et au lieu d'utiliser le modèle d'exception standard, vous pouvez plutôt appeler $ ceci-> Errorhander () (maintenant que j'y pense que vous pouvez mettre en place Quelques paramètres ici - éventuellement l'exception que vous obtenez de la déclaration de capture). Cela devrait vous donner ce dont vous avez besoin pour les parties du code que vous attendez des problèmes.

La partie suivante que nous devons comprendre est de gérer les exceptions que vous n'êtes pas attendu et de la manière dont vous envisagez de les acheminer via ce gestionnaire d'erreurs. Celui-ci est un peu plus délicat car cette solution s'appuie sur un bloc d'essai / attraper quelque part. Comme il s'agit d'un cadre, je vais supposer que tout fonctionne via Index.php ou un autre fichier bootstrap (quelque chose comme Zend Craywork ou similaire). Si tel est le cas, je mettrais votre essai / attraperais partout où l'exection du cadre commence. Sur la base de l'exception que vous obtenez dans le bloc de capture, vous pouvez décider si vous souhaitez l'exécuter via votre méthode d'erreurHandler (). Je dois administrer cette partie en quelque sorte se sent un peu sale et qu'il devrait y avoir une meilleure façon de le faire (peut-être une fois que vous aurez plus loin dans une meilleure solution se présentera).

Espérons que cela vous aide à aller plus loin dans votre processus. Si quelqu'un a une idée de savoir comment obtenir la dernière partie ne se sent pas si sale qui serait géniale.


0 commentaires

2
votes

excuses à l'avance pour ne pas essayer cela avant de poster:

Le cinquième (facultatif) paramètre que PHP passe à la méthode de votre gestionnaire d'erreur (et qui est typiquement ignoré) est un tableau $ ERRContext qui pointe vers la table Symbole PHP actuelle. Ma pensée est que si vous pouvez extraire l'espace de noms de la backtrage d'une exception proposée par Rudie, il peut également également être possible d'extraire des informations d'espace de noms de la même manière à partir de $ ERRContext. Si cela est vrai, votre gestionnaire d'erreur peut vérifier son propre espace de noms et "tomber" en retournant false si l'espace de noms actuel ne correspond pas à celui pour lequel le gestionnaire d'erreur est conçu.

En outre, les gestionnaires d'erreur peuvent être "empilés", ce qui signifie qu'au moins en principe (si ma suggestion à "mine" $ errcontext fonctionne réellement) Vous pouvez définir un gestionnaire d'erreur distinct pour chaque espace de noms.

Je ne prétends pas que cette approche est plus "élégante" que les solutions proposées par Josh et Rudie, mais cela semble être conforme à ce que vous essayez de faire - ce qui est d'imposer une sorte de Contrainte de slimage sur votre gestionnaire d'erreur.

bonne chance!


2 commentaires

Merci, c'était vraiment utile. $ errcontext n'était pas exactement ce que j'espérais, mais j'ai eu de bonnes idées. Je définirai un gestionnaire d'erreur dans un objet, qui a une pile de noms de fonctions de rappel stockés dans une matrice statique (puisque Set_error_handler vient de remplacer les fonctions précédemment définies). Ensuite, j'utilise call_user_func pour chaque fonction et vérifiez les valeurs de retour. Dans ces fonctions, je vais utiliser des idées combinées de réponses de Rudie et Josh. Il est en fait honte qu'il n'y ait pas de mise en œuvre native (que je suis au courant) pour empiler des gestionnaires d'erreur. C'est moche, cher ... ça marche.


En fait, Set_error_Handler () ne Nursez pas les gestionnaires d'erreur déclarés précédemment déclarés - Il en appute une nouvelle sur la "pile" et l'interpréteur PHP l'appelle d'abord lors de la manipulation d'une erreur. Si votre nouveau gestionnaire d'erreur quitte alors aucun des gestionnaires d'erreur restants dans la pile n'est appelé (il est donc comme si vous les avez rejetés), mais si votre gestionnaire d'erreur renvoie la valeur FALSE, le gestionnaire d'erreur suivant dans la pile est appelé. IMO, il serait plus propre de laisser PHP gérer votre "pile de fonctions de rappel" qu'il ne serait pas de les charger dans un tableau vous-même, mais bien sûr que cela pourrait fonctionner.