servidor - cómo redirigir STDOUT a un archivo en PHP?
descargar archivos php de un servidor ajeno (7)
Aquí hay una solución fea que fue útil para un problema que tuve (necesito depurar).
if(file_get_contents("out.txt") != "in progress")
{
file_put_contents("out.txt","in progress");
$content = file_get_contents(''http://''.$_SERVER[''HTTP_HOST''].$_SERVER[''REQUEST_URI'']);
file_put_contents("out.txt",$content);
}
El inconveniente principal de eso es que será mejor que no use las variables $ _POST. Pero no tienes que ponerlo en el principio.
El siguiente código casi funciona, pero no es lo que realmente quise decir:
ob_start();
echo ''xxx'';
$contents = ob_get_contents();
ob_end_clean();
file_put_contents($file,$contents);
¿Hay una forma más natural?
Es posible escribir STDOUT directamente en un archivo en PHP, lo que es mucho más sencillo y directo que usar el buffer de salida.
Haz esto desde el comienzo de tu script:
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen(''/dev/null'', ''r'');
$STDOUT = fopen(''application.log'', ''wb'');
$STDERR = fopen(''error.log'', ''wb'');
¿Por qué al principio puedes preguntar? Aún no se deben abrir los descriptores de archivos porque, al cerrar los descriptores estándar de entrada, salida y archivo de error, los primeros tres nuevos descriptores se convertirán en los NUEVOS descriptores estándar de entrada, salida y archivo de error.
En mi ejemplo, redirigí la entrada estándar a / dev / null y los descriptores de archivos de salida y error para registrar archivos. Esta es una práctica común al hacer un script daemon en PHP.
Para escribir en el archivo application.log , esto sería suficiente:
echo "Hello world/n";
Para escribir en error.log , uno debería hacer:
fwrite($STDERR, "Something went wrong/n");
Tenga en cuenta que cuando cambie los descriptores de entrada, salida y error, las constantes de PHP incorporadas STDIN, STDOUT y STDERR quedarán inutilizables. PHP no actualizará estas constantes a los nuevos descriptores y no está permitido redefinir estas constantes (se llaman constantes por un motivo, después de todo).
Ninguna de las respuestas funcionó para mi caso particular en el que necesitaba una forma cruzada de redireccionamiento de la salida tan pronto como se hizo eco para poder seguir los registros con tail -f log.txt u otra aplicación de visualización de registro. Se me ocurrió la siguiente solución:
$logFp = fopen(''log.txt'', ''w'');
ob_start(function($buffer) use($logFp){
fwrite($logFp, $buffer);
}, 1); //notice the use of chunk_size == 1
echo "first output/n";
sleep(10)
echo "second output/n";
ob_end_clean();
No he notado ningún problema de rendimiento, pero si lo hace, puede cambiar chunk_size a valores mayores.
Ahora solo la cola -f el archivo de registro:
tail -f log.txt
No, el buffer de salida es tan bueno como se pone. Aunque es un poco mejor simplemente hacer
ob_start();
echo ''xxx'';
$contents = ob_get_flush();
file_put_contents($file,$contents);
Puedes instalar la extensión Eio
pecl instalar eio
y duplicar un descriptor de archivo
$temp=fopen(''/tmp/my_stdout'',''a'');
$my_data=''my something'';
$foo=eio_dup2($temp,STDOUT,EIO_PRI_MAX,function($data,$esult,$request){
var_dump($data,$esult,$request);
var_dump(eio_get_last_error($request));
},$my_data);
eio_event_loop();
echo "something to stdout/n";
fclose($temp);
esto crea un nuevo descriptor de archivo y reescribe la secuencia de destino de STDOUT
esto se puede hacer con STDERR también
y las constantes STD [OUT | ERR] todavía se pueden usar
Usar eio pecl module eio es muy fácil, también puedes capturar errores internos de PHP, var_dump, echo, etc. En este código, puedes encontrar algunos ejemplos de situaciones diferentes.
$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);
// output examples
echo "message to stdout/n";
$v2dump = array(10, "graphinux");
var_dump($v2dump);
// php internal error/warning
$div0 = 10/0;
// user errors messages
fwrite(STDERR, "user controlled error/n");
La llamada a eio_event_loop se usa para asegurarse de que se hayan procesado las solicitudes eio anteriores. Si necesita adjuntar en el registro, en la llamada fopen, use el modo ''ab'' en lugar de ''wb''.
Instalar el módulo eio es muy fácil ( http://php.net/manual/es/eio.installation.php ). Probé este ejemplo con la versión 1.2.6 del módulo eio.
aquí hay una forma de desviar SALIDA que parece ser el problema original
$ob_file = fopen(''test.txt'',''w'');
function ob_file_callback($buffer)
{
global $ob_file;
fwrite($ob_file,$buffer);
}
ob_start(''ob_file_callback'');
más información aquí:
http://my.opera.com/zomg/blog/2007/10/03/how-to-easily-redirect-php-output-to-a-file