Bonsoir,
À l'origine, une grosse colère, enfin non mais ça me soûlait de ne pas afficher correctement mes var_dump, voire pas du tout dans certains cas.
Et je ne voulais pas écrire un css rien que pour le dev.
Alors je me suis décidé à écrire dans un fichier ce que je voulais tracker et, en fouillant sur la toile, je suis rapidement tombé sur une classe créée par dbunic et me convenant presque parfaitement : Write to a log file with PHP.
Je n'ai eu qu'à l'adapter pour logger le contenu de variables.
Je place le fichier de définition de la classe (loglib.inc.php) dans le dossier include de mon plugin :
<?php
/*
Copyright (c) 2008-2012, www.redips.net All rights reserved.
Code licensed under the BSD License: http://www.redips.net/license/
*/
/**
* Logging class:
* - contains lfile, lwrite and lclose public methods
* - lfile sets path and name of log file
* - lwrite writes message to the log file (and implicitly opens log file)
* - lclose closes log file
* - first call of lwrite method will open log file implicitly
* - message is written with the following format: [d/M/Y:H:i:s] (script name) message
*/
class Logging {
// declare log file and file pointer as private properties
private $log_file, $fp;
// set log file (path and name)
public function lfile($path) {
$this->log_file = $path;
}
// write message to the log file
public function lwrite($message, $var = null) {
// if file pointer doesn't exist, then open log file
if (!is_resource($this->fp)) {
$this->lopen();
}
// define script name
$script_name = pathinfo($_SERVER['PHP_SELF'], PATHINFO_FILENAME);
// define current time and suppress E_WARNING if using the system TZ settings
// (don't forget to set the INI setting date.timezone)
$time = @date('[d/M/Y:H:i:s]');
// write current time, script name and message to the log file
fwrite($this->fp, "$time ($script_name) $message" . PHP_EOL);
if ($var) {
fwrite($this->fp, print_r($var, true) . PHP_EOL);
}
}
// close log file (it's always a good idea to close a file when you're done with it)
public function lclose() {
fclose($this->fp);
}
// open log file (private method)
private function lopen() {
// in case of Windows set default log file
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$log_file_default = 'c:/php/logfile.txt';
}
// set default log file for Linux and other systems
else {
$log_file_default = '/tmp/logfile.txt';
}
// define log file from lfile method or use previously set default
$lfile = $this->log_file ? $this->log_file : $log_file_default;
// open log file for writing only and place file pointer at the end of the file
// (if the file does not exist, try to create it)
$this->fp = fopen($lfile, 'a') or exit("Can't open $lfile!");
}
}
?>Je n'utilise pas le dossier de log système : je suis sous Debian et l'accès à certains sous-dossiers de /var/log est réservé à root. Au lieu de ça, je crée un dossier logs à la racine du piwigo (à éviter en prod), avec les droits pour www-data.
Dans ce dossier sera écrit un fichier mylog.txt.
L'utilisation est ultra simple : là où je veux débugger, j'instancie la classe, je lui indique le fichier de destination dans lequel j'écris ce que je veux, puis je ferme le fichier.
include_once(PHPWG_PLUGINS_PATH.basename(dirname(__FILE__)).'/include/loglib.inc.php');
$log = new Logging();
$log->lfile(PHPWG_ROOT_PATH.'logs/mylog.txt');
$log->lwrite('function install');
$log->lwrite('default_options', $this->default_options);
$log->lclose();En parallèle, le fichier mylog.txt est ouvert dans mon éditeur et je n'ai qu'à le recharger après exécution du code.
Attention : cet include_once est valable pour travailler dans le dossier racine du plugin. Alors autant adapter le chemin exact suivant les besoins.
Voilà qui a bien changé ma vie : je n'ai plus à scruter l'écran à la recherche d'indices.
Dernière modification par polowigo (2025-05-13 18:56:27)
Hors ligne
Bonjour Franta,
Ce n'est pas nécessaire si on ne souhaite pas le consulter.
Mais quand j'en ai besoin en développement, il est ouvert en permanence dans mon éditeur Geany qui me propose de recharger le fichier quand il a été modifié par Piwigo.
En revanche, de mémoire ça plante si le fichier n'existe pas. Il faudrait donc ajouter une ligne pour vérifier son existence et en créer un si besoin.
Sinon ça me sert pas mal quand je recherche un bug précis et parfois en parallèle au mode debug de Piwigo.
Hors ligne
Bonjour polowigo,
Pour moi Piwigo est installé sur un NAS Synology, et c'est quasi impossible de trouver où sont écrits les error_log
Dans le main.inc.php du plugin que je veux débuguer je mets ce code :
// Logs -------------------------------------- à activer pour débugage
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', './plugins/nom_du_plugin/debug.log');Les logs se retrouvent dans le fichier debug.log dans le répertoire du plugin, lisible directement depuis l'éditeur. ( pour moi VSCode sous windows )
Il faut penser à désactiver ce code, sinon le fichier de log va augmenter de taille sans arrêt.
Après je ne sais pas si c'est comparable avec la méthode que tu proposes ?
Hors ligne
Bonsoir Charles69,
Oui je pense que dans le principe c'est équivalent.
À la différence près que souvent j'essaye de traquer l'origine d'un résultat non souhaité et qui ne renvoie pas forcément en erreur.
Ce que je veux dans ces cas-là, c'est avoir la valeur de certaines variables à certaines étapes clés du flux, comme si j'avais placé des points d'arrêt.
C'est très confortable mais, pour ne rien cacher, ça m'évite surtout d'apprivoiser les outils du navigateur...
Et je suis d'accord : ne surtout pas oublier de désactiver le code après usage. :-)
Hors ligne
polowigo a écrit:
À la différence près que souvent j'essaye de traquer l'origine d'un résultat non souhaité et qui ne renvoie pas forcément en erreur.
contrairement à ce que son nom pourrait laisser entendre 'error_log' n'est pas appelé par une erreur, c'est comme 'console.log' mais pour du php
exemples :
error_log('DEBUT DEBUGAGE');
error_log('Position du bouton : ' . $button_position);
error_log('Error writing image via PHP Imagick: ' . $e->getMessage());
error_log('Image Path : '.$image_path) ;
error_log(print_r($variable, true));
error_log('tableau : ' . print_r($Array, true));
error_log('FIN DEBUGAGE');
Hors ligne
Bonjour,
Alors j'ai fait quelques essais sur un thème.
J'ai mis le code d'initialisation dans le themeconf et des appels dans différentes fonctions du themecontroller.
Il n'y a pas d'énormes différences entre les deux méthodes :
- une nuance dans la présentation des dates ;
- avec la classe, l'indication de la fonction dans laquelle les appels sont placés.
On peut donc dire que les deux méthodes sont équivalentes.
Sinon je viens d'avoir une idée saugrenue : je me demande si il y aurait une façon de s'en servir dans un template via smarty, genre {error_log('ma variable : '.$ma_variable) } mais je ne pense pas. Il faudra que je fouille dans le code de la popup de smarty en mode debug.
Hors ligne