registros - consultas dinamicas mysql php ajax
Ejecutar proceso con salida en tiempo real en PHP (10)
A continuación, se describe una solución mejor a este viejo problema utilizando los eventos paralelos del servidor HTML5 moderno:
http://www.w3schools.com/html/html5_serversentevents.asp
Ejemplo:
http://sink.agiletoolkit.org/realtime/console
Código: https://github.com/atk4/sink/blob/master/admin/page/realtime/console.php#L40
(Implementado como un módulo en el marco de Agile Toolkit)
Estoy intentando ejecutar un proceso en una página web que devolverá su resultado en tiempo real. Por ejemplo, si ejecuto el proceso ''ping'' debería actualizar mi página cada vez que devuelve una nueva línea (en este momento, cuando uso exec (comando, salida) me veo obligado a usar la opción -c y esperar hasta que el proceso termine para ver el salida en mi página web). ¿Es posible hacer esto en php?
También me pregunto cuál es la forma correcta de matar este tipo de proceso cuando alguien abandona la página. En el caso del proceso ''ping'' todavía puedo ver el proceso ejecutándose en el monitor del sistema (lo que tiene sentido).
Comprueba todas las respuestas, nada funciona ...
Solución encontrada Here
Funciona en Windows (creo que esta respuesta es útil para los usuarios que buscan allí)
<?php
$a = popen(''ping www.google.com'', ''r'');
while($b = fgets($a, 2048)) {
echo $b."<br>/n";
ob_flush();flush();
}
pclose($a);
?>
Esta es una buena forma de mostrar la salida en tiempo real de los comandos de su shell:
<?php
header("Content-type: text/plain");
// tell php to automatically flush after every output
// including lines of output produced by shell commands
disable_ob();
$command = ''rsync -avz /your/directory1 /your/directory2'';
system($command);
Necesitará esta función para evitar el almacenamiento en búfer de salida:
function disable_ob() {
// Turn off output buffering
ini_set(''output_buffering'', ''off'');
// Turn off PHP output compression
ini_set(''zlib.output_compression'', false);
// Implicitly flush the buffer(s)
ini_set(''implicit_flush'', true);
ob_implicit_flush(true);
// Clear, and turn off output buffering
while (ob_get_level() > 0) {
// Get the curent level
$level = ob_get_level();
// End the buffering
ob_end_clean();
// If the current level has not changed, abort
if (ob_get_level() == $level) break;
}
// Disable apache output buffering/compression
if (function_exists(''apache_setenv'')) {
apache_setenv(''no-gzip'', ''1'');
apache_setenv(''dont-vary'', ''1'');
}
}
Sin embargo, no funciona en todos los servidores en los que he probado, me gustaría poder ofrecerle consejos sobre qué buscar en su configuración de php para determinar si debe o no peinarse tratando de hacer funcionar este tipo de comportamiento. en tu servidor! ¿Alguien más sabe?
Aquí hay un ejemplo ficticio en PHP simple:
<?php
header("Content-type: text/plain");
disable_ob();
for($i=0;$i<10;$i++)
{
echo $i . "/n";
usleep(300000);
}
Espero que esto ayude a otros que han buscado en Google aquí.
Esto funcionó para mí:
$cmd = "ping 127.0.0.1";
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath(''./''), array());
echo "<pre>";
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
}
echo "</pre>";
Intente cambiar el conjunto de archivos php.ini "output_buffering = Off". Debería poder obtener la salida en tiempo real en la página Usar el comando del sistema en lugar de la ejecución. El comando del sistema vaciará la salida
Para el uso de línea de comandos:
function execute($cmd) {
$proc = proc_open($cmd, [[''pipe'',''r''],[''pipe'',''w''],[''pipe'',''w'']], $pipes);
while(($line = fgets($pipes[1])) !== false) {
fwrite(STDOUT,$line);
}
while(($line = fgets($pipes[2])) !== false) {
fwrite(STDERR,$line);
}
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
return proc_close($proc);
}
Si está intentando ejecutar un archivo, es posible que primero necesite otorgarle permisos de ejecución:
chmod(''/path/to/script'',0755);
Primero verifica si flush() funciona para ti. Si lo hace, bueno, si no es así, probablemente significa que el servidor web se está almacenando en el búfer por algún motivo, por ejemplo, mod_gzip está habilitado.
Para algo como ping, la técnica más fácil es hacer un bucle dentro de PHP, ejecutar "ping -c 1" varias veces y llamar a flush () después de cada salida. Asumiendo que PHP está configurado para abortar cuando el usuario cierra la conexión HTTP (que generalmente es la predeterminada, o puede llamar a ignore_user_abort (false) para asegurarse), entonces no necesita preocuparse por los procesos de ping en ejecución. .
Si es realmente necesario que solo ejecute el proceso secundario una vez y muestre continuamente su salida, puede ser más difícil: probablemente deba ejecutarlo en segundo plano, redireccionar la salida a una transmisión y luego hacer que PHP repita esa secuencia de vuelta al usuario, intercalado con llamadas flush () regulares.
Probé varios comandos de ejecución de PHP en Windows y descubrí que difieren bastante.
- No trabaje para la transmisión:
shell_exec
,exec
,passthru
- Tipo de trabajos:
proc_open
,popen
- "tipo de" porque no puede pasar argumentos a su comando (es decir, no funcionará conmy.exe --something
, funcionará con_my_something.bat
).
El mejor (más fácil) enfoque es:
- Debes asegurarte de que tu ejecutor está descargando comandos (mira el problema de descarga de printf ). Sin esto, lo más probable es que reciba lotes de aproximadamente 4096 bytes de texto, haga lo que haga.
- Si puede, use el
header(''Content-Type: text/event-stream'');
(en lugar deheader(''Content-Type: text/plain; charset=...'');
). Sin embargo, esto no funcionará en todos los navegadores / clientes. Streaming funcionará sin esto, pero al menos las primeras líneas serán almacenadas por el navegador. - También es posible que desee deshabilitar el
header(''Cache-Control: no-cache'');
cachéheader(''Cache-Control: no-cache'');
. - Desactive el almacenamiento en búfer de salida (ya sea en php.ini o con
ini_set(''output_buffering'', ''off'');
). Esto también podría tener que hacerse en Apache / Nginx / cualquier servidor que use al frente. - Giro de compresión (ya sea en php.ini o con
ini_set(''zlib.output_compression'', false);
). Esto también podría tener que hacerse en Apache / Nginx / cualquier servidor que use al frente.
Entonces en su programa C ++ usted hace algo como (de nuevo, para otras soluciones vea el problema de descarga de printf ):
Logger::log(...) {
printf (text);
fflush(stdout);
}
En PHP, haces algo como:
function setupStreaming() {
// Turn off output buffering
ini_set(''output_buffering'', ''off'');
// Turn off PHP output compression
ini_set(''zlib.output_compression'', false);
// Disable Apache output buffering/compression
if (function_exists(''apache_setenv'')) {
apache_setenv(''no-gzip'', ''1'');
apache_setenv(''dont-vary'', ''1'');
}
}
function runStreamingCommand($cmd){
echo "/nrunning $cmd/n";
system($cmd);
}
...
setupStreaming();
runStreamingCommand($cmd);
Si está buscando ejecutar comandos del sistema a través de PHP, investigue la documentación del ejecutivo .
Sin embargo, no recomendaría hacer esto en un sitio con mucho tráfico, por lo que un proceso para cada solicitud es un proceso bastante grande. Algunos programas ofrecen la opción de escribir su ID de proceso en un archivo para que pueda verificar y finalizar el proceso a voluntad, pero para comandos como ping, no estoy seguro de que eso sea posible, consulte las páginas man.
Puede ser mejor atendido simplemente abriendo un socket en el puerto que espera escuchar (IE: puerto 80 para HTTP) en el host remoto, de esa manera usted sabe que todo va bien en el territorio del usuario, así como en la red.
Si está intentando generar datos binarios, busque en la función de encabezado de php y asegúrese de configurar el content-type content-disposition content-type correctos. Revise la documentación para obtener más información sobre cómo usar / deshabilitar el búfer de salida.
intente esto (probado en Windows machine + wamp server)
header(''Content-Encoding: none;'');
set_time_limit(0);
$handle = popen("<<< Your Shell Command >>>", "r");
if (ob_get_level() == 0)
ob_start();
while(!feof($handle)) {
$buffer = fgets($handle);
$buffer = trim(htmlspecialchars($buffer));
echo $buffer . "<br />";
echo str_pad('''', 4096);
ob_flush();
flush();
sleep(1);
}
pclose($handle);
ob_end_flush();