PHP: Как читать файл в реальном времени, в который постоянно пишут - PullRequest
12 голосов
/ 10 июля 2010

Я хочу прочитать файл журнала, в который постоянно пишется. Он находится на том же сервере, что и приложение. Уловка в том, что файл записывается каждые несколько секунд, и я в основном хочу tail файл приложения в режиме реального времени.

Возможно ли это?

Ответы [ 5 ]

23 голосов
/ 10 июля 2010

Вы должны зацикливаться во сне:

$file='/home/user/youfile.txt';
$lastpos = 0;
while (true) {
    usleep(300000); //0.3 s
    clearstatcache(false, $file);
    $len = filesize($file);
    if ($len < $lastpos) {
        //file deleted or reset
        $lastpos = $len;
    }
    elseif ($len > $lastpos) {
        $f = fopen($file, "rb");
        if ($f === false)
            die();
        fseek($f, $lastpos);
        while (!feof($f)) {
            $buffer = fread($f, 4096);
            echo $buffer;
            flush();
        }
        $lastpos = ftell($f);
        fclose($f);
    }
}

(проверено .. работает)

3 голосов
/ 20 августа 2018

Да, вам нужно поспать некоторое время в цикле, но вам не нужно повторно открывать файл.Я просто искал похожую проблему.Я хотел прочитать файл, который мог быть изменен с момента последнего чтения.

Проблема в том, что ресурс достиг конца файла (EOF).И не продолжает читать.Решение состоит в том, чтобы сбросить указатель с помощью fseek($fh, ftell($fh)).

Полная программа, ожидающая ввода в текстовом файле, может выглядеть так:

1 голос
/ 10 июля 2010

Например:

$log_file = '/tmp/test/log_file.log';

$f = fopen($log_file, 'a+');
$fr = fopen($log_file, 'r' );

for ( $i = 1; $i < 10; $i++ )
{
    fprintf($f, "Line: %u\n", $i);
    sleep(2);
    echo fread($fr, 1024) . "\n";
}

fclose($fr);
fclose($f);

//Or if you want use tail

$f = fopen($log_file, 'a+');

for ( $i = 1; $i < 10; $i++ )
{
    fprintf($f, "Line: %u\n", $i);
    sleep(2);
    $result = array();
    exec( 'tail -n 1 ' . $log_file, $result );
    echo "\n".$result[0];
}

fclose($f);
0 голосов
/ 10 июля 2010

вы можете закрыть дескриптор файла, когда он не используется (после записи части данных). или вы можете использовать буфер для хранения данных и помещать их в файл, только когда он заполнен. таким образом, файл не будет открыт постоянно.

если вы хотите получить все, что записано в файл, сразу после его записи, вам может понадобиться расширить код, записав данные, чтобы он также выводился в другие места (экран, некоторая переменная, другой файл ...)

0 голосов
/ 10 июля 2010

Просто идея ..

Думали ли вы использовать команду * nix tail? выполните команду из php (с параметром, который вернет определенное количество строк) и обработайте результаты в вашем php-скрипте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...