function tail($file,&$pos) {
$buf = "";
if(!$pos) $pos = filesize($file);
$fd = inotify_init();
$watch_descriptor = inotify_add_watch($fd, $file, IN_ALL_EVENTS);
while (true) {
$events = inotify_read($fd);
foreach ($events as $event=>$evdetails) {
switch (true) {
case ($evdetails['mask'] & IN_MODIFY):
inotify_rm_watch($fd, $watch_descriptor);
fclose($fd);
$fp = fopen($file,'r');
if (!$fp) return false;
fseek($fp,$pos);
while (!feof($fp)) {
$buf .= fread($fp,8192);
}
$pos = ftell($fp);
fclose($fp);
return $buf;
break;
case ($evdetails['mask'] & IN_MOVE):
case ($evdetails['mask'] & IN_MOVE_SELF):
case ($evdetails['mask'] & IN_DELETE):
case ($evdetails['mask'] & IN_DELETE_SELF):
inotify_rm_watch($fd, $watch_descriptor);
fclose($fd);
return false;
break;
}
}
}
}
$file = "test.txt";
$lastpos = 0;
while (true) {
echo tail($file,$lastpos);
}
需要pecl install inotify。
在实际测试过程中,通过运行以上的测试程序监视一个文件,还遇到过两个奇怪的现象:用vim编辑那个被监视的文件,修改并保存,触发的是IN_DELETE_SELF和IN_MOVE_SELF事件而不是我们所期望的IN_MODIFY事件;再次修改并保存的时候不再有任何事件发生。希望能给看官一个教训,其实这是由于vim的工作机制引起的,vim会先将源文件复制为另一个文件,然后在另一文件基础上编辑(一般后缀名为swp),保存的时候再将这个文件覆盖源文件,因此会出现上述的第一个现象,第二个现象是因为原来的文件已经被后来的新文件代替,因此监视对象所监视的文件已经不存在了,所以自然不会产生任何事件。