Page 1 sur 1

Modelisation d'une classe Log/Erreur/Affichag

Posté : 12 mars 2006, 13:15
par Lorenzo
salut,


ca fait deja un bon petit bout de temps que j'utilise une classe "Log" qui est la mere de toutes mes autres classes : elle sert pour l'ensemble de la gestion d'erreurs ainsi que l'affichage me permettant de deboguer + facilement (log dans fichier/affichage erreur/gestionnaire d'erreur perso "error_handler()"/mail/...)


Un des principes de fonctionnement de la classe Log :
des constantes sont definis dans un fichier de config qui lui indique l'action qu'elle doit executer suivant le niveau de l'erreur rencontré (SUCCESS/NOTICE/WARNING/FATAL).
Ce niveau est generalement definit pour l'ensemble de l'appli mais peut etre adapté a chaqu'une des classes.


La question metaphysiques :
Imaginons maintenant que je prefere definir un niveau d'erreur perso qui peut etre defini pour chaque methode afin de pouvoir en laisser certaines continuer le script en cas d'erreur tandis que d'autre doivent obligatoirement le couper (pour une question de sécu par exemple) !


Qu'elles seraient vos idées pour implanter cette possibilitée sans que les methodes ou fonctions deviennent des usines a gaz :?:

Posté : 12 mars 2006, 13:35
par naholyr
Tu utilises la gestion d'exception intégrée à PHP avec les constantes E_NOTICE & cie ?
Sans avoir la moindre idée de la façon dont est motorisée ta classe Log on peut difficilement avoir une idée :?

Posté : 12 mars 2006, 16:48
par Lorenzo
le probleme ou l'inconnu ne vient pas de la classe LOG !
c'est plutot comment gerer un niveau d'erreur perso pour toutes les methodes des autres classes sans avoir X vars supplémentaires a passer en arguments de chaque methodes.

Posté : 12 mars 2006, 17:12
par zeus
Donc, comme te le demande naholyr, est-ce que tu t'es penché sur la gestion des erreurs PHP 5 ?

Posté : 12 mars 2006, 17:34
par Lorenzo
si tu causes des try/catch, PAS DU TOUT -> ce systeme me deplait ... ca oblige a modifier l'integralité du code !! sans oublier que le code ne devient plus portable ! donc tant que PHP5 n'occupera pas 90% des serveurs, je zappe ...

je prefere les conditions placés aux bons endroits qui appellent eventuellement un gestionnaire d'erreur perso et pour celles qui sont non previsibles une methode pour le set_error_handler() suffit .

Posté : 12 mars 2006, 22:14
par naholyr
Bon je vais être plus clair alors sur ma demande ;)
Il y a 1000 façons d'implémenter un loggeur d'erreurs, donc si on ne sait pas quelle est la tienne, il est absolument impossible de deviner.

Je crois comprendre que tu "actives" ton loggeur avec set_error_handler(), et que tu déclenches manuellement si nécessaire avec trigger_error(). C'est la question que je te posais, et si c'est bien ça tu es restreint aux constantes prédéfinies par PHP : les E_* mais également les E_USER_* qui peuvent du coup résoudre partiellement ton problème.

Posté : 12 mars 2006, 23:08
par Lorenzo
voila tout le probleme, je ne voulais pas etre trop precis pour ne pas influencer vos reponses et surtout pour voir si la direction est la bonne.

comme disait l'autre zigoto (matrix :lol:) :
"il y a une difference entre connaitre le chemin et arpenter le chemin"


pour infos le set_error_handler() ne sert que pour les erreurs que je n'ai pas prevu, les autres sont gérés avec des conditions sur les retours des methodes/fonctions ...etc


voici un bout de code qui te permettra de comprendre un peu mieux comment elle fonctionne.
la methode est un classique de ce que tu trouves dans un classe MySQL et gere le changement de base de données :
        /**
        * Selection de la base de données MySQL
        *
        * @param String $stBd La base de données
        *
        * @return Boolean
        */
        public function myBd($stBd){
                @mysqli_select_db($this->rsPtMy, $stBd);
                if( @mysqli_errno($this->rsPtMy) ){
                        return $this->logHandler(
                                "class Mysql->myBd() :<br />Erreur lors de la selection de la base de données :<br />".@mysqli_error($this->rsPtMy),
                                LOG_LV_FATAL
                        );
                }

                $this->logHandler(
                        "class Mysql->myBd() :<br />Selection de la base de données :<br />".$stBd,
                        LOG_LV_NOTICE
                );
                $this->stBdMy = $stBd;
                return true;
        }

voici ce qu'il y a dans le fichier config pour gerer les erreurs des applis :
// ---------------------------------------------------------------------
// ------------------- PARTIE A NE PAS MODIFIER ----------------------
// ---------------------------------------------------------------------

error_reporting(E_ALL);
set_time_limit(6000);




/**
*  Log : Actions on error
*/
define('LOG_DISPLAY_SUCCESS', 1);
define('LOG_DISPLAY_NOTICE', 2);
define('LOG_DISPLAY_WARNING', 4);
define('LOG_DISPLAY_FATAL', 8);

define('LOG_WRITE_SUCCESS', 16);
define('LOG_WRITE_NOTICE', 32);
define('LOG_WRITE_WARNING', 64);
define('LOG_WRITE_FATAL', 128);

define('LOG_HALT_ON_FATAL', 256);

/**
*  Log : formating data
*/
define('LOG_DISPLAY_TEXT', 0);
define('LOG_DISPLAY_HTML', 1);
define('LOG_DISPLAY_FLASH', 2);
define('LOG_DISPLAY_XML', 3);

/**
*  Log : levels for log to file/display (Level for Log::logHandler())
*/
define('LOG_LV_SUCCESS', 1);
define('LOG_LV_NOTICE', 2);
define('LOG_LV_WARNING', 4);
define('LOG_LV_FATAL', 8);

$GLOBALS['tbLog'] = array(
	LOG_LV_SUCCESS => array('type'=>'SUCCESS', 'color'=>'green'),     // 0
	LOG_LV_NOTICE => array('type'=>'NOTICE', 'color'=>'steelblue'),   // 1
	LOG_LV_WARNING => array('type'=>'WARNING', 'color'=>'#FF9900'), // 2
	LOG_LV_FATAL => array('type'=>'FATAL', 'color'=>'red')             // 3
);




// ---------------------------------------------------------------------
// ------------ CONFIGURATION DE LA GESTION DES ERREURS -----------
// ---------------------------------------------------------------------

/*
* Level for handle the error
*
* LOG_DISPLAY_SUCCESS = Display SUCCESS to screen
* LOG_DISPLAY_NOTICE = Display NOTICE to screen
* LOG_DISPLAY_WARNING = Display WARNING to screen
* LOG_DISPLAY_FATAL = Display FATAL Error to screen
*
* LOG_WRITE_SUCCESS = Write SUCCESS to log file
* LOG_WRITE_NOTICE = Write NOTICE to log file
* LOG_WRITE_WARNING = Write WARNING to log file
* LOG_WRITE_FATAL = Write FATAL Error to log file
*
* LOG_HALT_ON_FATAL = Halt script on FATAL Error
*
* Combine differents choices
*/
define('LOG_ERROR_LEVEL',
	LOG_DISPLAY_SUCCESS +
	//LOG_DISPLAY_NOTICE +
	//LOG_DISPLAY_WARNING +
	LOG_DISPLAY_FATAL +
	LOG_WRITE_SUCCESS +
	//LOG_WRITE_NOTICE +
	//LOG_WRITE_WARNING +
	LOG_WRITE_FATAL +
	LOG_HALT_ON_FATAL
);

/**
* Format for displaying Log
*
* LOG_DISPLAY_TEXT = return text Log
* LOG_DISPLAY_HTML = return text Log embed in HTML
* LOG_DISPLAY_FLASH = return text Log URL-encoded (for Flash player)
* LOG_DISPLAY_XML = return text Log with XML TAG
*
* One choice
*/
define('LOG_FORMAT_TO_DISPLAY', LOG_DISPLAY_HTML);

Posté : 12 mars 2006, 23:17
par naholyr
Okay je crois avoir compris le problème ^^

Si j'étais toi je modifierais la méthode logHandler() afin qu'elle renvoi un booléen : true = continuer, false = stopper.
Ainsi ton appel $this->logHandler("mon message", LOG_LV_*)
deviendrait if (!$this->logHandler("mon message", LOG_LV_*) return;
Et dans ta méthode logHandler() tu n'as qu'à tester la valeur de ton LOG_LV_* pour savoir si tu renvoies false (stopper l'exécution de la fonction en cours), ou true (continuer).

Exemple :
class Loggable {
  var $stopLevels = array();
  function log($message, $level) {
    echo $message;
    return !in_array($stopLevels, $level);
  }
}

class MaClasse extends Loggable {
  function MaClasse () {
    $this->stopLevels = array(LOG_LV_FATAL);
  }
  function fonctionQuiContinue() {
    echo "debut";
    if (!$this->log("message", LOG_LV_WARNING)) return;
    echo "fin";
  }
  function fonctionQuiNeContinuePas() {
    echo "debut";
    if (!$this->log("message", LOG_LV_FATAL)) return;
    echo "fin";
  }
}

Posté : 13 mars 2006, 00:06
par Lorenzo
dans le 1er script :
return $this->logHandler( ..... 
la methode renvoit deja un booleen, TRUE pour un SUCCESS et FALSE sinon

--------------------
pour en revenir a ma "question metaphysique" :
le but serait de pouvoir configurer hors de la classe LOG ou du fichier de config, et donc sans etre obligé de retoucher le code trop en profondeur comme rajouter X variables en arguments a chaque fonction afin de personnaliser chaque action de ces methodes en cas d'erreur.

Posté : 13 mars 2006, 00:09
par naholyr
Je comprends vraiment pas ce que tu veux dire désolé :?

Posté : 13 mars 2006, 00:24
par Lorenzo
c'est pas grave, merci les gars, je crois que je vais faire un autre sujet avec comme titre :
comment feriez vous une classe LOG :D