16

我想用 PHP 进行诸如 tail 命令之类的动作,但是如何将 watch 追加到文件中呢?

4

6 回答 6

24

我不相信有什么神奇的方法可以做到这一点。您只需要不断地轮询文件大小并输出任何新数据。这实际上很容易,唯一需要注意的是文件大小和其他统计数据缓存在 php.ini 中。解决方案是clearstatcache()在输出任何数据之前调用。

这是一个快速示例,不包括任何错误处理:

function follow($file)
{
    $size = 0;
    while (true) {
        clearstatcache();
        $currentSize = filesize($file);
        if ($size == $currentSize) {
            usleep(100);
            continue;
        }

        $fh = fopen($file, "r");
        fseek($fh, $size);

        while ($d = fgets($fh)) {
            echo $d;
        }

        fclose($fh);
        $size = $currentSize;
    }
}

follow("file.txt");
于 2009-07-09T07:27:53.963 回答
11
$handle = popen("tail -f /var/log/your_file.log 2>&1", 'r');
while(!feof($handle)) {
    $buffer = fgets($handle);
    echo "$buffer\n";
    flush();
}
pclose($handle);
于 2013-01-04T20:31:05.967 回答
5

在 Google 代码上结帐php-tail。这是一个使用 PHP 和 Javascript 的 2 文件实现,在我的测试中它的开销很小。

它甚至支持使用 grep 关键字进行过滤(对于每秒吐出帧速率等的 ffmpeg 很有用)。

于 2012-12-11T12:52:54.193 回答
2
$handler = fopen('somefile.txt', 'r');

// move you at the end of file
fseek($handler, filesize( ));
// move you at the begining of file
fseek($handler, 0);

也许你会想考虑使用stream_get_line

于 2009-07-09T07:17:12.300 回答
2

您可以定期检查文件修改时间,而不是轮询文件大小:filemtime

于 2009-07-09T09:31:17.413 回答
0

以下是我从上面改编的。使用 ajax 调用定期调用它并附加到您的“持有人”(textarea)...希望这会有所帮助...感谢所有为 stackoverflow 和其他此类论坛做出贡献的人!

/* Used by the programming module to output debug.txt */
session_start();
$_SESSION['tailSize'] = filesize("./debugLog.txt");
if($_SESSION['tailPrevSize'] == '' || $_SESSION['tailPrevSize'] > $_SESSION['tailSize'])
{
      $_SESSION['tailPrevSize'] = $_SESSION['tailSize'];
}
$tailDiff = $_SESSION['tailSize'] - $_SESSION['tailPrevSize'];
$_SESSION['tailPrevSize'] = $_SESSION['tailSize'];

/* Include your own security checks (valid user, etc) if required here */

if(!$valid_user) {
   echo "Invalid system mode for this page.";
}
$handle = popen("tail -c ".$tailDiff." ./debugLog.txt 2>&1", 'r');
while(!feof($handle)) {
    $buffer = fgets($handle);
    echo "$buffer";
    flush(); 
}
pclose($handle);
于 2016-04-15T13:02:42.567 回答