【问题标题】:Outputting exec() ping result progressively逐步输出 exec() ping 结果
【发布时间】:2012-05-29 22:27:50
【问题描述】:

我正在尝试编写一个 ping 几百个地址并返回其值(毫秒)的函数。到目前为止,我已经实现了 ping 并获得结果的最初想法,但是当对数百个地址使用相同的代码时会出现问题,PHP 页面会停止,直到它超时或到达最后一个 ping 命令。

如果我能得到一些建议来逐步输出结果,我会很高兴,这是我当前的代码:

<?php

// "for" loop added according to suggestion for browser compatibility (IE, FF, CHR, OPR, SFR)
for($i = 0; $i < 5000; $i++)
{
    echo ' ';
}

function GetPing($ip = NULL) {
    // Returns the client ping if no address has been passed to the function
    if(empty($ip)) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    // Check which OS is being run by the client
    if(getenv('OS') == 'Windows_NT') {
        //echo '<b>Detected local system:</b> Windows NT/2000/XP/2003/2008/Vista/7<p>';
        $exec = exec("ping -n 1 -l 32 -i 128 " . $ip);
        return end(explode(' ', $exec));
    }
    else {
        //echo '<b>Detected local system:</b> Linux/Unix<p>';
        $exec = exec("ping -c 1 -s 32 -t 128 " . $ip);
        $array = explode('/', end(explode('=', $exec )));
        return ceil($array[1]) . 'ms';
    }
    // ob_flush and flush added according to suggestion for buffer output
    ob_flush();
    flush();
}

// Added to test 20 sequential outputs
for($count = 0; $count < 20; $count++)
    echo GetPing('8.8.8.8') . '<div>';

?>

经过一些反馈,我在脚本中添加了一个 for 循环以及 ob_flush() 和 flush(),我还在 php.ini 中将 output_buffering 设置为 0 。它似乎适用于我迄今为止测试过的大多数浏览器(IE8、Firefox 12、Chrome 19、Opera 11、Safari 5)。目前的代码似乎正在按预期工作,但任何改进它的建议都非常感谢。

感谢您的反馈。

【问题讨论】:

  • 看看fping。与传统的 ping 相比,它可以更轻松地处理 ping 多个主机,并且输出更容易被软件解析。

标签: php buffer exec ping flush


【解决方案1】:

这只是一个猜测;几年前我写过一个非常不稳定的聊天脚本,它也使用了输出缓冲(并在 while(true) 循环中获取新消息)..

在执行此操作时,我遇到了相同的问题,有时脚本会停止(空白屏幕),有时需要一段时间才能出现字符,而且这也是特定于浏览器的。

这是我添加到脚本中的相关代码 sn-ps 以使其与 IE6 和 FF2 一起使用(正如我所说,多年前......)

<?php
    // End output buffering
    ob_end_flush(); 

    // IE and Safari Workaround
    // They will only display the webpage if it's completely loaded or
    // at least 5000 bytes have been "printed".
    for($i=0;$i<5000;$i++)
    {
        echo ' ';
    }

    while( ... )
    {
        echo 'Message';
        ob_flush();
        flush();
    }
?>

它对我有用,所以也许你也可以尝试一下。 (尽管我不知道现代浏览器和服务器基础设施对此有何表现)。

【讨论】:

  • 非常感谢 GeneSys,“for”循环对于解决问题至关重要,在测试过程中,我有时不得不关闭浏览器并重新打开它才能正常工作。它适用于以下浏览器:IE8、Firefox 12、Chrome 19、Opera 11。我更新了代码以反映实际情况。谢谢。
  • 它现在给出这个错误: 注意:ob_flush(): failed to flush buffer。没有要刷新的缓冲区
【解决方案2】:

我认为您可能正在寻找的是逐步运行和输出脚本,而不是异步函数。

Is there a way to make PHP progressively output as the script executes?

【讨论】:

  • 感谢您的提示 nomaD,但我无法使其正常工作。首先,我在 php.ini 中将 output_buffering 设置为 0,并更新了代码以包含 ob_flush() 和 flush()。虽然我知道 ob_flush() 之前不应该在没有 ob_start() 的情况下使用,但这是我让它实时逐步输出结果的唯一方法,但这只是因为 PHP 输出警告通知:注意: ob_flush() [ref.outcontrol]: 刷新缓冲区失败。没有要刷新的缓冲区。奇怪的是,如果我修复代码并包含 ob_start(),我不会像以前那样得到任何实时输出。
猜你喜欢
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
相关资源
最近更新 更多