ob_start ob_get_contents limpiar clean php output-buffering

ob_get_contents - php clean output buffer



Cómo vaciar los datos al navegador pero continuar ejecutando (7)

Lo he hecho en el pasado y así lo resolví:

ob_start(); /* * Generate your output here */ // Ignore connection-closing by the client/user ignore_user_abort(true); // Set your timelimit to a length long enough for your script to run, // but not so long it will bog down your server in case multiple versions run // or this script get''s in an endless loop. if ( !ini_get(''safe_mode'') && strpos(ini_get(''disable_functions''), ''set_time_limit'') === FALSE ){ set_time_limit(60); } // Get your output and send it to the client $content = ob_get_contents(); // Get the content of the output buffer ob_end_clean(); // Close current output buffer $len = strlen($content); // Get the length header(''Connection: close''); // Tell the client to close connection header("Content-Length: $len"); // Close connection after $len characters echo $content; // Output content flush(); // Force php-output-cache to flush to browser. // See caveats below. // Optional: kill all other output buffering while (ob_get_level() > 0) { ob_end_clean(); }

Como dije en un par de comentarios antes, debes tener cuidado con tu contenido, ya que eso alterará la longitud de tu contenido, pero no cambiará el encabezado al respecto. También puede amortiguar su salida, por lo que no se enviará al cliente al instante.
Puede intentar que Apache sepa que no debe descomprimir su contenido usando apache_setenv(''no-gzip'', ''1''); . Pero esto no funcionará si usa reglas de reescritura para ir a su página, ya que también modificará esas variables de entorno. Al menos, lo hizo por mí.

Vea más advertencias sobre la descarga de su contenido al usuario en el manual .

Tengo un ob_start() y un ob_flush() correspondiente. Me gustaría vaciar una parte de los datos y continuar ejecutando el resto. Usar ob_flush() no ayudó. Además, si es posible, el descanso debe ocurrir sin mostrar la carga en el navegador.

EDITAR:

No quiero usar ajax


Si está utilizando PHP-FPM:

ignore_user_abort(true); fastcgi_finish_request();

Sobre dos funciones están los factores clave que ignore_user_abort evita el error y fastcgi_finish_request cierra la conexión del cliente.



Utilizar:

header("Content-Length: $len");

..where $len es la longitud de los datos que se deben vaciar al cliente.

No tengo el fondo para saber cuándo y dónde va a funcionar esto, pero probé en algunos navegadores, y todos regresaron al instante con:

<?PHP header("Content-length:5"); echo "this is more than 5"; sleep(5); ?>

edición: Chrome, IE y Opera mostraron this , mientras que FireFox mostró que this is more than 5 . Sin embargo, todos ellos cerraron la solicitud después de eso.


esta es mi funcion

function bg_process($fn, $arr) { $call = function($fn, $arr){ header(''Connection: close''); header(''Content-length: ''.ob_get_length()); ob_flush(); flush(); call_user_func_array($fn, $arr); }; register_shutdown_function($call, $fn, $arr); }

Envuelva la función que se ejecutará al final, después de que PHP cierre la conexión. y por supuesto el navegador detendrá el almacenamiento en búfer.

function test() { while (true) { echo ''this text will never seen by user''; } }

Así es como se llama a la función.

bg_process(''test'');

el primer argumento es callable , el segundo argumento es una matriz que se pasa a la función de "prueba" con una matriz indexada

Nota: no uso ob_start() al principio de la secuencia de comandos.


fastcgi_finish_request

Esta función vacía todos los datos de respuesta al cliente y finaliza la solicitud. Esto permite realizar tareas que consumen mucho tiempo sin dejar abierta la conexión con el cliente.

no funciona en Apache. (PHP 5> = 5.3.3, PHP 7)


ob_flush escribe el búfer. En otras palabras, ob_flush le dice a PHP que le dé a Apache (o nginx / lighttpd / lo que sea) la salida y luego a PHP para que se olvide de ello. Una vez que Apache tiene la salida, hace lo que quiere con ella. (En otras palabras, después de ob_flush queda fuera de su control si se escribe inmediatamente o no en el navegador).

Entonces, respuesta corta: no hay una forma garantizada de hacerlo.

Sólo una conjetura, es probable que estés buscando AJAX. Cuando las personas intentan manipular cuando el contenido de la página se carga como lo está haciendo, AJAX es casi siempre la ruta correcta.

Si desea continuar una tarea en segundo plano, puede usar ignore_user_abort , como se detalla here , sin embargo, a menudo este no es el enfoque óptimo. Básicamente, se pierde el control sobre ese hilo, y en mi opinión, un hilo del servidor web no es a donde pertenece el procesamiento pesado.

Intentaría extraerlo de las cosas de la web. Esto podría significar una entrada cron o simplemente generar un proceso en segundo plano desde PHP (un proceso que aunque comenzó desde adentro de la ejecución del script no morirá con el script, y el script no esperará a que termine antes de morir).

Si va por esa ruta, significará que incluso puede hacer algún tipo de sistema de estado si es necesario. Luego, puede supervisar la ejecución y proporcionar al usuario actualizaciones periódicas sobre el progreso. (Técnicamente, también podría crear un sistema de estado con un script ignore_user_abort -ed, pero no me parece tan limpio).