PHP passthru()/system() 调用和输出缓冲的挂起问题
PHP hang issue with passthru()/system() call and output buffering
我有个奇怪的问题。我试图绕过 PHP 到 运行 system() 调用中的输出缓冲并获得即时输出。它运行良好,但由于某些奇怪的原因,"test.de" 上的 ping 命令不像 google.de 上的 ping 命令那样显示即时输出。我确实立即在 linux shell 中看到了 'ping test.de' 的第一行,但它不会立即出现在这个脚本中。有人可以帮忙吗?
<?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 \n\n";
passthru("ping -w 10 -c 4 google.de");
echo "\n\nPinging test.de \n\n";
passthru("ping -w 10 -c 4 test.de");
echo '</pre>';
?>
我在这个输出中标记了延迟行:
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
我认为这是因为您正在使用 system()
函数,因为它只会 return 最后一行。您可能更适合使用 passthru()
或 exec()
函数。这是一篇关于这些函数的作用及其区别的精彩文章:
根据评论更新
您可能还想尝试将输出参数附加到 shell 脚本。将 2>&1
附加到行尾,它会将每个新的 shell 输出行放入一个变量中。它应该是这样的:
exec("ping -w 10 -c 4 google.de 2>&1", $output );
print_r( $output );
解法:
显然它与 linux 缓冲有关。我修改了 shell 命令,现在可以使用了。解决办法是用script
命令包裹linux命令。所以:
passthru("script -q -c 'ping -w 10 -c 4 test.de' /dev/null")
这篇文章帮助了:https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe
我有个奇怪的问题。我试图绕过 PHP 到 运行 system() 调用中的输出缓冲并获得即时输出。它运行良好,但由于某些奇怪的原因,"test.de" 上的 ping 命令不像 google.de 上的 ping 命令那样显示即时输出。我确实立即在 linux shell 中看到了 'ping test.de' 的第一行,但它不会立即出现在这个脚本中。有人可以帮忙吗?
<?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 \n\n";
passthru("ping -w 10 -c 4 google.de");
echo "\n\nPinging test.de \n\n";
passthru("ping -w 10 -c 4 test.de");
echo '</pre>';
?>
我在这个输出中标记了延迟行:
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
我认为这是因为您正在使用 system()
函数,因为它只会 return 最后一行。您可能更适合使用 passthru()
或 exec()
函数。这是一篇关于这些函数的作用及其区别的精彩文章:
根据评论更新
您可能还想尝试将输出参数附加到 shell 脚本。将 2>&1
附加到行尾,它会将每个新的 shell 输出行放入一个变量中。它应该是这样的:
exec("ping -w 10 -c 4 google.de 2>&1", $output );
print_r( $output );
解法:
显然它与 linux 缓冲有关。我修改了 shell 命令,现在可以使用了。解决办法是用script
命令包裹linux命令。所以:
passthru("script -q -c 'ping -w 10 -c 4 test.de' /dev/null")
这篇文章帮助了:https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe