Le code ci-dessous fonctionne presque, mais ce n'est pas vraiment ce que je voulais :
ob_start();
echo 'xxx';
$contents = ob_get_contents();
ob_end_clean();
file_put_contents($file,$contents);
Y a-t-il un moyen plus naturel ?
Le code ci-dessous fonctionne presque, mais ce n'est pas vraiment ce que je voulais :
ob_start();
echo 'xxx';
$contents = ob_get_contents();
ob_end_clean();
file_put_contents($file,$contents);
Y a-t-il un moyen plus naturel ?
Il est possible d'écrire directement STDOUT dans un fichier en PHP, ce qui est beaucoup plus facile et plus direct que d'utiliser un tampon de sortie.
Faites ceci au tout début de votre script:
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('application.log', 'wb');
$STDERR = fopen('error.log', 'wb');
Pourquoi au tout début me direz-vous? Aucun descripteur de fichier ne devrait être ouvert à ce moment, car lorsque vous fermez les descripteurs de fichier d'entrée, de sortie et d'erreur standard, les trois premiers nouveaux descripteurs deviendront les NOUVEAUX descripteurs de fichier d'entrée, de sortie et d'erreur.
Dans mon exemple, j'ai redirigé l'entrée standard vers /dev/null et les descripteurs de sortie et d'erreur vers des fichiers journaux. C'est une pratique courante lors de la création d'un script daemon en PHP.
Pour écrire dans le fichier application.log, cela suffirait:
echo "Bonjour le monde\n";
Pour écrire dans le fichier error.log, il faudrait faire:
fwrite($STDERR, "Quelque chose s'est mal passé\n");
Veuillez noter que lorsque vous changez les descripteurs d'entrée, de sortie et d'erreur, les constantes PHP intégrées STDIN, STDOUT et STDERR deviendront inutilisables. PHP ne mettra pas à jour ces constantes avec les nouveaux descripteurs et il n'est pas autorisé à redéfinir ces constantes (elles sont appelées constantes pour une raison après tout).
C'est le comportement de base Unix (c'est aussi pourquoi il n'est pas portable sur Windows). Unix attribue le plus petit descripteur de fichier disponible à un fichier. Étant donné que les fcloses ferment les descripteurs 0, 1 et 2, ils deviennent disponibles pour les 3 ouvertures suivantes. De plus, Unix est extraordinaire par sa simplicité.
Voici une façon de détourner la SORTIE qui semble être le problème d'origine
$ob_file = fopen('test.txt','w');
function ob_file_callback($buffer)
{
global $ob_file;
fwrite($ob_file,$buffer);
}
ob_start('ob_file_callback');
plus d'infos ici :
http://my.opera.com/zomg/blog/2007/10/03/how-to-easily-redirect-php-output-to-a-file
Si vous utilisez PHP 5.3 ou une version plus récente, je vous suggère d'utiliser une fonction de fermeture sans avoir besoin que $ob_file
soit global : $ob_file_callback = function($buffer) use ($ob_file) { fwrite($ob_file, $buffer); }; ob_start($ob_file_callback);
Aucune des réponses n'a fonctionné pour mon cas particulier où j'avais besoin d'une façon multiplateforme de rediriger la sortie dès qu'elle était affichée afin de suivre les journaux avec tail -f log.txt ou une autre application de visualisation de journaux. J'ai trouvé la solution suivante:
$logFp = fopen('log.txt', 'w');
ob_start(function($buffer) use($logFp){
fwrite($logFp, $buffer);
}, 1); //remarquez l'utilisation de chunk_size == 1
echo "première sortie\n";
sleep(10)
echo "deuxième sortie\n";
ob_end_clean();
Je n'ai remarqué aucun problème de performance, mais si vous en voyez, vous pouvez modifier chunk_size pour de plus grandes valeurs.
Maintenant, suivez simplement le fichier journal avec tail -f:
tail -f log.txt
Utiliser le module eio pecl eio est très facile, vous pouvez également capturer des erreurs internes de PHP, var_dump, echo, etc. Dans ce code, vous trouverez quelques exemples de différentes situations.
$fdout = fopen('/tmp/stdout.log', 'wb');
$fderr = fopen('/tmp/stderr.log', 'wb');
eio_dup2($fdout, STDOUT);
eio_dup2($fderr, STDERR);
eio_event_loop();
fclose($fdout);
fclose($fderr);
// exemples de sortie
echo "message à stdout\n";
$v2dump = array(10, "graphinux");
var_dump($v2dump);
// erreur/avertissement interne PHP
$div0 = 10/0;
// messages d'erreurs utilisateur
fwrite(STDERR, "erreur contrôlée par l'utilisateur\n");
L'appel à eio_event_loop est utilisé pour s'assurer que les requêtes eio précédentes ont été traitées. Si vous avez besoin d'ajouter des journaux, lors de l'appel à fopen, utilisez le mode 'ab' au lieu de 'wb'.
L'installation du module eio est très facile (http://php.net/manual/es/eio.installation.php). J'ai testé cet exemple avec la version 1.2.6 du module eio.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
Vous devriez vraiment accepter une réponse ici. Bas Peters vous a donné la solution parfaite.
1 votes
Le code d'exemple redirige la SORTIE vers un fichier, pas vers STDOUT, la solution de Bas semble fonctionner uniquement parce que les environnements CLI (et dans une moindre mesure CGI) utilisent ces flux de manière interchangeable. Le module PHP Apache ne le fait pas.