Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour à tous.
Je débute avec le Zend Framework (1.7) et je bloque sur l'utilisation de Zend_Log.
En fait l'erreur que je fais s'affiche directement dans le navigateur et n'est pas interceptée par zend_log.
voici mon code :
<?php
// Inclusion du composant Zend_Loader
include('Zend/Loader.php');
// Déclaration du chargement automatique
Zend_Loader::registerAutoload();
// Création d'un objet Zend_Log
$log = new Zend_Log();
// Enregistrement du journal sur l'écran (affichage)
$writer = new Zend_Log_Writer_Stream('php://output');
// Ajout de l'enregistreur dans l'objet log
$log->addWriter($writer);
try
{
$obj->method();
}
catch(Exception $e)
{
$log->log($e, Zend_Log::INFO);
}
Dans firefox :
Fatal error: Call to undefined method stdClass::method() in /****/******/**/apr/www/public/test/zend_log.php on line 20
Si quelqu'un peu m'aider.
Par avance merci.
Hors ligne
Je pense que cela ne fonctionne pas car le fait que l'objet ne soit pas instancié lève une fatal error qui si je ne dis pas de bétises n'est pas catchable directement. Il vaudrait mieux faire ceci pour que cela fonctionne :
<?php class Demo{ public function __construct() { } public function method1($param = null) { if (!is_string($param)) { throw new Exception('Param must be a string !'); } // traitement normal // ... } } // Inclusion du composant Zend_Loader include('Zend/Loader.php'); // Déclaration du chargement automatique Zend_Loader::registerAutoload(); // Création d'un objet Zend_Log $log = new Zend_Log(); // Enregistrement du journal sur l'écran (affichage) $writer = new Zend_Log_Writer_Stream('php://output'); // Ajout de l'enregistreur dans l'objet log $log->addWriter($writer); try { $obj = new Demo(); $obj->method1(223); } catch(Exception $e) { $log->log($e, Zend_Log::INFO); }
Ce qui renverra dans le navigateur
2009-04-03T11:45:30+02:00 INFO (6): exception 'Exception' with message 'Param must be a string !' in C:\wamp\www\heritage\index.php:11 Stack trace: #0 C:\wamp\www\heritage\index.php(37): Demo->method1(223) #1 {main}
Evidemment, il ne faut pas imbriquer une classe et un fichier comme je l'ai fais ici, mais ça vous le savez déjà bien sur....
Cordialement,
Hors ligne
You're welcome !
Hors ligne
en effet, PHP n'étant pas un langage objet (en ce sens que tout n'est pas objet en PHP, même s'il dispose d'un modèle objet assez complet), il distingue clairement les erreurs (héritées de l'époque procédurale) et les exceptions, mécanisme de gestion d'erreur propre au développement orienté objet.
En résumé, une erreur n'étant pas une exception, elle n'est pas "attrapée".
Si tu veux implémenter une gestion d'erreur par exception (ce qui est une bonne idée ), voici une astuce très simple (issue du manuel PHP) :
function exception_error_handler($errno, $errstr, $errfile, $errline ) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } set_error_handler("exception_error_handler");
Ces quelques lignes de code vont interceptées toutes les erreurs et jeter des Exceptions d'un type particulier (ErrorException) de sorte que 1) toutes les erreurs pourront être attrapées 2) elles pourront être identifiées comme telles :
try { fonctionInconnue(); } catch (ErrorException $e) { // une erreur s'est produite et a été transformée en Exception } catch(MyException $e) { // une exception a été levée dans un objet métier } catch (Exception $e) { // une exception générique a été levée (probablement par un objet natif du langage) }
ainsi, tu peux gérer tes exceptions en une seule fois (dans le ZF, tu peux faire autour du Zend_Front_Controller::getInstance()->dispatch();, ou mieux, dans le ErrorController::errorAction) tout en identifiant parfaitement leur origine.
Hors ligne
c'est une très bonne idée mais malheureusement incompatible avec certaine partie de ZF
exemple:
tu mets ton set_error_handler dans le index.php (dès le début)
puis dans le bootstrap tu utilise DocType sur ta vue
ZF va alors utiliser Zend_Loader_PluginLoader pour charger le Helper Doctype.php
mais ne sachant pas vraiment ou le chercher il vas commencer pas ./view/helpers/Doctype.php voir si tu n'en as pas un à toi puis dans ZF
mais est c'est là que ça ce complique il vas pour cela utiliser la méthode isReadable de Zend_Load
cette méthode doit retourner true si le fichier est lisible et false sinon
c'est simple sauf qu'elle est très mal écrite elle fait un @fopen (Beurrk) simple et efficace mais pas propre
@ va empêcher la fonction de planter et donc si le ./view/helpers/Doctype.php n'existe pas pourvoir te retourner true
mais avec ton handler le @ ne sert plus à rien vu que l'erreur et transformé en exception
la méthode isRedable va planter et tu ne pourras pas charger ton plugin
Il faut signer une pétition pour l'éradication de @
il suffit de remplacer
public static function isReadable($filename) { if (!$fh = @fopen($filename, 'r', true)) { return false; } @fclose($fh); return true; }
par
public static function isReadable($filename) { try { if (!$fh = @fopen($filename, 'r', true)) { return false; } @fclose($fh); return true; } catch (Exception $e) { return false; } }
ou mieux
public static function isReadable($filename) { return is_readable($filename); }
ce qui est tout de même vachement plus propre
sinon pour ton code tu peux faire directement
set_error_handler(create_function('$errno, $errstr, $errfile, $errline','throw new ErrorException($errstr, 0, $errno, $errfile, $errline);'));
ainsi tu n'a pas un fonction qui traine mais tu as tout de même ta gestion des erreur en exception.
A+JYT
Hors ligne
pour revenir au sujet de départ
set_error_handler(create_function('$errno, $errstr, $errfile, $errline','global $log; $log->log($errno." ".$errstr." ".$errfile." ".$errline, Zend_Log::ERROR);'));
en clair lorsqu'une erreur survient l'écrire dans le fichier de log
A+JYT
Hors ligne
sekaijin a écrit:
Il faut signer une pétition pour l'éradication de @
Je plussoie ! C'est où que l'on signe ?
Dernière modification par elkolonel (07-04-2009 09:14:41)
Hors ligne
Hello,
Pour tester s'il y a un @, il suffit juste de faire if ($errno ==0) {return;}
A+
Hors ligne