tail functionality in PHP
Posted on 12th June 2008 in PHP | 16 Comments »
This little PHP code snippet could come in handy for those in a need to display most recent entries in a considerably heavy text file, e.g. Apache log.
In UNIX environments there’s tail, that does the trick of displaying last few lines in a text file, e.g.
tail -n 10 /home/clients/tekkie.flashbit.net/logs/default-error.log |
for the last 10 lines of Apache error log. On the remote server this kind of tool is the subject of SSH access or the possibility of using proc_open or exec functions of PHP to call tail. Mostly, esp. on the virtual servers, this is not the case.
The above reasoning is exactly why this code is a handy tool:
Download the code.


16 Responses
This script is really useful. Thanks.
Thank you very much. I modified slightly the code for letting the user change the number of lines using a GET variable.
You may want to check if the file exists before you try to read it.
Absolutely. You are welcome to modify as Fjor has already quite rightly done it.
Thanks. Quite useful.
Extremely useful in for the small project I work on. However, if you could update it to use Ajax for example to constantly update the info without reloading the page would be magic. I have searched this on the web for a few hours and tried a few scripts but nothing really works.
Maybe I’ll start from this script to make the update myself….. although I am not an programmer.
Thanks,
It’s a splendid idea indeed! Shouldn’t be too hard to do either.
Subscribe to the RSS, I’ll make sure to publish it once I have a spare hour.
Nice code, just what I was looking for, thx.
wow, thanks, I was just thinking how I would open the last 10 lines of my 150Mb log file without putting all of them into a buffer and swapping lines
fgets() does not read long lines.
The following version does workaround it:
function read_file($filename, $lines_to_read) {
$text = ”;
$pos = -1;
$handle = fopen($filename, ‘r’);
while ($lines_to_read > 0) {
–$pos;
if(fseek($handle, $pos, SEEK_END) !== 0) {
rewind($handle);
$lines_to_read = 0;
} elseif (fgetc($handle) === “\n”) {
–$lines_to_read;
}
$block_size = (-$pos) % 8192;
if ($block_size === 0 || $lines_to_read === 0) {
$text = fread($handle, ($block_size === 0 ? 8192 : $block_size)) . $text;
}
}
fclose($handle);
return $text;
}
echo read_file(TEXT_FILE, LINES_COUNT);
I’ve written a PHP Tail class using parts of this code. You can view the source here: http://code.google.com/p/php-tail/
Doesn’t this approach end up reading the entire file once, thus, since it does not start at the end, it will use a lot of cpu cycles seeking to the end if let’s say your log file grew to 2GB?
fopen doesn’t read the whole file into memory. The scripts sets the pointer at the end and reads line by line up to LINES_COUNT, which at any reasonable count shouldn’t have an impact.
Let me know if it runs out of memory though!
Thanks for the code, very useful! Had to use for line breaks since \n’s didn’t work otherwise perfect.
Just for completion, I had to use the BR tag instead of \n for linebreaks.
Is this method public domain? Can I use it as AGPL?
Thanks!