2012-01-06 14 views
5

Estoy usando PHP 5.3.4 con Apache 2.2.17 en un sistema Windows 7 x64. Me gustaría que mi página PHP salga como resultado de una llamada system en tiempo real al navegador del usuario. Con ese fin, he configurado output_buffering=Off en php.ini y ha creado este código:salida del proceso de impresión en tiempo real

<?php 
ob_implicit_flush(true); 
ob_end_flush(); 
system('ping -n 10 www.google.com'); 
?> 

El resultado de la mesa de ping se imprime en tiempo real, sino también recibo un error de diagnóstico y pila de llamadas PHP en la parte superior de mi página que dice:

Notice: ob_end_flush() [ref.outcontrol]: failed to delete and flush buffer. No buffer to delete or flush in index.php on line 3 

¿Qué debo hacer para corregir o suprimir este error?

actualización Si cambio ob_end_flush() a $a = 1/0; me sale un error similar y la salida es en tiempo real en todos los navegadores. ¿Hay algo en la forma en que se imprime la excepción que hace que esto funcione?

+2

Quitar 'ob_end_flush();' – Grexis

+0

Si lo quito o suprimir con un @, la salida ya no es en tiempo real en Chrome 16 o Firefox 10. (Aunque funciona en IE9) – PaulH

+0

Eso es extraño, pero vea mi respuesta a continuación. – Grexis

Respuesta

6

algunos navegadores web amortiguan la primera x bytes antes de que comiencen a presentar una página, bajo ciertas condiciones.

intentar dar salida solo un montón de espacio en blanco primer

+0

Sí. Este era el problema. ¡Gracias! – PaulH

+2

Tuve que hacer un eco exacto de 894 caracteres en el navegador para habilitar la salida en tiempo real. Probado en Firefox 21 e IE 8. – Clarkey

0

En su código, el error es bastante fácil de interpretar.

Llama a ob_end_flush() en la línea 3, pero (como dice el error), no hay salida para enjuagar. En esencia, la línea 3 es inútil porque no se ha enviado ninguna salida, por lo que al eliminar la línea se solucionará el error. Si esto se incorpora a un archivo más grande, es posible que deba conservar ob_end_flush() porque es posible que ya se haya capturado alguna salida.

EDIT: Ya que se necesita para tirar de la cadena, ya sea:

a: añadir ob_start(); a la parte superior del archivo.

B, reemplace con ob_end_flush();flush();

Edit2: Puesto que no parece la primera vez a trabajar, esto es lo mejor que puedo ofrecer: How to echo output in real time, (before script finishes)?

+0

Si lo elimino, la salida ya no está en tiempo real en Chrome 16 o Firefox 10. (Aunque sí funciona en IE9) – PaulH

+0

según su edición - Con el cambio A, no está en tiempo real en ningún navegador. Con el cambio B, es en tiempo real solo en IE9. – PaulH

+0

@PaulH Echa un vistazo a la respuesta a la pregunta que he vinculado. Similar, y probablemente el mismo problema. – Grexis

0

ob_end_flush() vacía el búfer de salida php, y requiere un buffer de salida activo creado con ob_start().

Creo que solo quiere llamar a flush() para enviar los datos al cliente.

<?php 
ob_implicit_flush(true); 
flush(); 
system('ping -n 10 www.google.com'); 
?> 
+0

Con este código, la salida no es en tiempo real en Chrome 16 o Firefox 10. (Aunque esto sí funciona en IE9) – PaulH

+0

Creo que los navegadores (Chrome 16 y ff10) están guardando en caché el texto antes de representarlo. Iría con javascript + ajax, obtendría un resultado de ping a la hora y se lo mostraría al usuario. Me interesaría una manera confiable de forzar la representación de la página también ... – al01

+0

Puedo hacerlo funcionar perfectamente si estoy dispuesto a tolerar un diálogo de excepción en la parte superior de la página. No creo que los navegadores sean incapaces de hacer esto. – PaulH

3

Tengo una solución que funciona, pero no es performant y repulsivo. Lanzo una excepción, pero escondo el diálogo de excepción.

<?php 
    ob_implicit_flush(true); 

    // Something about the way exceptions are thrown causes Firefox and Chrome 
    // to be able to display the results of the system call in real-time rather 
    // than having to wait for the call to complete. So, I just hide the 
    // exception message. IE9 works with or without this. 
    echo "<div style=\"display:none\">"; 
    $a = 1/0; 
    echo "</div>"; 

    echo "<pre>"; 
    system('ping -n 5 www.google.com'); 
    echo "</pre>"; 
?> 

Para el desplazamiento automático a la parte inferior de la página, agrego algunos javascript:

<html><head> 
<script language="javascript"> 
var int = self.setInterval("window.scrollBy(0,1000);", 200); 
</script> 
</head> 
<body> 
<?php 
    // insert above php code here 
    // stop scrolling when the execution finishes 
    echo '<script language="javascript">int = window.clearInterval(int);</script>'; 
?> 
</body> 
</html> 

EDITAR

@ respuesta de Chris muestra una solución mucho mejor.

echo '<div style="display:none">'; 
for ($a = 0; $a < 768; $a++) 
    echo ' '; 
echo '</div>'; 
1

Sólo tiene que añadir esto a vaciar el búfer:

if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) { 
     echo "<div style=\"display:none\">"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";  
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";  
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
     echo "</div>"; 
    } 

Tiene que ser dentro del bucle. o entre dos salidas que necesita mostrar en tiempo real.

y aquí está el truco abreviada:

añadir lo siguiente:

if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) { 
    echo "<div style=\"display:none\"></div>";      
} 
Cuestiones relacionadas