PHP挂起问题与passthru()/ system()调用和输出缓冲

I do have a strange problem. I'm trying to get around output buffering in PHP to run system() calls and get instant output. It works very well, but for some strange reason, the ping command on "test.de" isn't presenting instant output as the ping on google.de does. I do see the first line for 'ping test.de' in the linux shell instantly, but it doesn't appear instantly with this script. Anyone can help?

<?php

  // 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');
  }

  header('Cache-Control: no-cache');

  $i=0;
  while( $i < 1000 ) {
    $i++;
    echo '                        ';
  }
  echo '<pre>';
  echo "Pinging google.de 

";
  passthru("ping -w 10 -c 4 google.de");
  echo "

Pinging test.de 

";
  passthru("ping -w 10 -c 4 test.de");
  echo '</pre>';
?>

I've marked the delayed line in this output:

Pinging google.de 

PING google.de (172.217.16.131) 56(84) bytes of data.
64 bytes from zrh04s06-in-f131.1e100.net (172.217.16.131): icmp_seq=1 ttl=56 time=22.0 ms
64 bytes from zrh04s06-in-f131.1e100.net (172.217.16.131): icmp_seq=2 ttl=56 time=22.0 ms
64 bytes from zrh04s06-in-f131.1e100.net (172.217.16.131): icmp_seq=3 ttl=56 time=22.2 ms
64 bytes from zrh04s06-in-f3.1e100.net (172.217.16.131): icmp_seq=4 ttl=56 time=22.0 ms

--- google.de ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 22.016/22.067/22.200/0.130 ms


Pinging test.de 

PING test.de (104.45.6.189) 56(84) bytes of data. <<<< THAT line is delayed!!

--- test.de ping statistics ---
11 packets transmitted, 0 received, 100% packet loss, time 9999ms

Solution:

Apparently it has something to do with linux buffering. I've reworked the shell command so it is working now. The solution is to wrap the linux command with the script command. So:

passthru("script -q -c 'ping -w 10 -c 4 test.de' /dev/null")

This article helped: https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe

I think it is because you are using the system() function as it will only return the last line. You might be better suited using the passthru() or exec() functions. Here is a great writeup on what these functions do and their differences:

https://stackoverflow.com/a/21016100/1789650

Update based on comments

You may also want to try appending an output argument to your shell script. Append 2>&1 to the end of your line and it will put each new shell output line into a variable. Here is what it should look like:

exec("ping -w 10 -c 4 google.de 2>&1", $output );
print_r( $output );