php 实现tailf
实现 PHP 的 tail -f 功能
PHP 可以通过多种方式模拟 Unix 的 tail -f 命令功能,实时监控文件的新增内容。以下是几种实现方法:

使用 fseek 和循环读取
这种方法通过记录文件指针位置并循环检查文件更新来实现:

function tailFile($filename) {
$file = fopen($filename, "r");
fseek($file, 0, SEEK_END); // 初始定位到文件末尾
while (true) {
$currentPos = ftell($file);
$fileSize = filesize($filename);
if ($fileSize < $currentPos) {
// 文件被截断(如日志轮转),重新打开
fclose($file);
$file = fopen($filename, "r");
fseek($file, 0, SEEK_END);
continue;
}
if ($fileSize > $currentPos) {
// 读取新增内容
$data = fread($file, $fileSize - $currentPos);
echo $data;
flush();
}
usleep(100000); // 暂停100毫秒减少CPU占用
}
}
tailFile('/path/to/your/file.log');
使用 inotify 扩展(Linux 系统)
如果服务器支持 inotify,可以实现更高效的文件监控:
if (!extension_loaded('inotify')) {
die("inotify extension not available");
}
function tailWithInotify($filename) {
$fd = inotify_init();
$watch = inotify_add_watch($fd, $filename, IN_MODIFY);
$fp = fopen($filename, "r");
fseek($fp, 0, SEEK_END);
stream_set_blocking($fd, 0); // 非阻塞模式
while (true) {
$events = inotify_read($fd);
if ($events) {
$data = fread($fp, 8192);
echo $data;
flush();
}
usleep(100000);
}
}
tailWithInotify('/path/to/your/file.log');
使用 SplFileObject 类
面向对象风格的实现方式:
function tailWithSpl($filename) {
$file = new SplFileObject($filename);
$file->seek(PHP_INT_MAX); // 定位到文件末尾
$lastLine = $file->key();
while (true) {
$file->seek($lastLine);
while (!$file->eof()) {
echo $file->current();
$file->next();
}
$lastLine = $file->key();
usleep(100000);
}
}
tailWithSpl('/path/to/your/file.log');
注意事项
- 以上方法都需要在命令行环境下运行
- 长时间运行脚本需考虑内存管理
- 对于日志轮转情况(log rotation),需要特殊处理
- 生产环境建议增加异常处理和日志记录
- 高性能场景可考虑使用专门的日志收集工具如 Fluentd 或 Logstash






