PHP - блокировка чтения файла - PullRequest
0 голосов
/ 17 октября 2010

У меня есть файл, который добавляется удаленно (file.txt).Из SSH я могу позвонить tail -f file.txt, чтобы отобразить обновленное содержимое файла.Я хотел бы иметь возможность блокировать вызов этого файла, который будет возвращать последнюю добавленную строку.Цикл объединения просто не вариант.Вот что я хотел бы:

$cmd = "tail -f file.txt";
$str = exec($cmd);

Проблема с этим кодом в том, что tail никогда не вернется.Есть ли какая-нибудь функция-обертка для tail, которая убьет его, когда он вернет содержимое?Есть ли лучший способ сделать это с минимальными накладными расходами?

Ответы [ 2 ]

1 голос
/ 17 октября 2010

Единственное решение, которое я нашел, несколько грязное:

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w")   // stderr
);

$process = proc_open('tail -f -n 0 /tmp/file.txt',$descriptorspec,$pipes);
fclose($pipes[0]);
stream_set_blocking($pipes[1],1);
$read = fgets($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);
//if I try to call proc_close($process); here, it fails / hangs untill a second line is
//passed to the file. Hence an inelegant kill in the next 2 line:
$status = proc_get_status($process);
exec('kill '.$status['pid']);
proc_close($process);
echo $read;
0 голосов
/ 17 октября 2010

tail -n 1 file.txt всегда будет возвращать вам последнюю строку в файле, но я почти уверен, что вы хотите, чтобы PHP знал, когда file.txt имеет новую строку, и отображал ее, все без опроса в цикл. * * +1002

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

Вы можете даже запустить php через cron, чтобы выполнить проверку, если вы не хотите, чтобы он запускался в цикле php (вероятно, лучше всего), или через скрипт оболочки, который выполняет цикл и вызывает файл php, если вам нужно суб 1-минутные пробеги, которые являются пределом cron.

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

...