I have a file named file.txt
which is update by adding lines to it.
I am reading it by this code:
$fp = fopen(\"file.txt\", \"r\");
$da
Untested code, but should work:
$file = file("filename.txt");
for ($i = max(0, count($file)-6); $i < count($file); $i++) {
echo $file[$i] . "\n";
}
Calling max
will handle the file being less than 6 lines.
This doesn't use file()
so it will be more efficient for huge files;
<?php
function read_backward_line($filename, $lines, $revers = false)
{
$offset = -1;
$c = '';
$read = '';
$i = 0;
$fp = @fopen($filename, "r");
while( $lines && fseek($fp, $offset, SEEK_END) >= 0 ) {
$c = fgetc($fp);
if($c == "\n" || $c == "\r"){
$lines--;
if( $revers ){
$read[$i] = strrev($read[$i]);
$i++;
}
}
if( $revers ) $read[$i] .= $c;
else $read .= $c;
$offset--;
}
fclose ($fp);
if( $revers ){
if($read[$i] == "\n" || $read[$i] == "\r")
array_pop($read);
else $read[$i] = strrev($read[$i]);
return implode('',$read);
}
return strrev(rtrim($read,"\n\r"));
}
//if $revers=false function return->
//line 1000: i am line of 1000
//line 1001: and i am line of 1001
//line 1002: and i am last line
//but if $revers=true function return->
//line 1002: and i am last line
//line 1001: and i am line of 1001
//line 1000: i am line of 1000
?>
I've tested this one. It works for me.
function getlast($filename,$linenum_to_read,$linelength){
// this function takes 3 arguments;
if (!$linelength){ $linelength = 600;}
$f = fopen($filename, 'r');
$linenum = filesize($filename)/$linelength;
for ($i=1; $i<=($linenum-$linenum_to_read);$i++) {
$data = fread($f,$linelength);
}
echo "<pre>";
for ($j=1; $j<=$linenum_to_read+1;$j++) {
echo fread($f,$linelength);
}
echo "</pre><hr />The filesize is:".filesize("$filename");
}
getlast("file.txt",6,230);
?>
Here is FAST method for LARGE files with LOW memory cost - I develop Wallace Maxters answer (if you want to upvote - do it on his answer) by wrap his code inside handy function and add reverse feature
function readLastLines($filename, $num, $reverse = false)
{
$file = new \SplFileObject($filename, 'r');
$file->seek(PHP_INT_MAX);
$last_line = $file->key();
$lines = new \LimitIterator($file, $last_line - $num, $last_line);
$arr = iterator_to_array($lines);
if($reverse) $arr = array_reverse($arr);
return implode('',$arr);
}
// use it by
$lines = readLastLines("file.txt", 5) // return string with 5 last lines
this is read last 10 line from text file
$data = array_slice(file('logs.txt'),10);
foreach ($data as $line)
{
echo $line."<br/>";
}
For a large file, reading all the lines into an array with file() is a bit wasteful. Here's how you could read the file and maintain a buffer of the last 5 lines:
$lines=array();
$fp = fopen("file.txt", "r");
while(!feof($fp))
{
$line = fgets($fp, 4096);
array_push($lines, $line);
if (count($lines)>5)
array_shift($lines);
}
fclose($fp);
You could optimize this a bit more with some heuristics about likely line length by seeking to a position, say, approx 10 lines from the end, and going further back if that doesn't yield 5 lines. Here's a simple implementation which demonstrates that:
//how many lines?
$linecount=5;
//what's a typical line length?
$length=40;
//which file?
$file="test.txt";
//we double the offset factor on each iteration
//if our first guess at the file offset doesn't
//yield $linecount lines
$offset_factor=1;
$bytes=filesize($file);
$fp = fopen($file, "r") or die("Can't open $file");
$complete=false;
while (!$complete)
{
//seek to a position close to end of file
$offset = $linecount * $length * $offset_factor;
fseek($fp, -$offset, SEEK_END);
//we might seek mid-line, so read partial line
//if our offset means we're reading the whole file,
//we don't skip...
if ($offset<$bytes)
fgets($fp);
//read all following lines, store last x
$lines=array();
while(!feof($fp))
{
$line = fgets($fp);
array_push($lines, $line);
if (count($lines)>$linecount)
{
array_shift($lines);
$complete=true;
}
}
//if we read the whole file, we're done, even if we
//don't have enough lines
if ($offset>=$bytes)
$complete=true;
else
$offset_factor*=2; //otherwise let's seek even further back
}
fclose($fp);
var_dump($lines);