View the last 5 lines of a file with PHP?

5

Through Shell , I can display the last 5 lines of a file using the tail command.

So:

> tail -n 5 public/index.php 

I'd like to do the same thing in PHP. But I did not want to load the whole file, but actually only display the last 5 lines.

I know you can display the first 5 like this:

$f = new SplFileObject('public/index.php');

$f->rewind();

for ($i = 0; $i < 5; $i++) {
    echo $f->fgets();
}

But how can I display the last 5 lines of a file while maintaining good performance?

Note : I do not want a solution where you have to open the command line via PHP.

    
asked by anonymous 02.09.2015 / 21:48

4 answers

4

The best performance solution I could develop was this:

$file = new SplFileObject('text.txt');
$file->seek(PHP_INT_MAX);

$linesTotal = $file->key();
$startLine = $linesTotal - 5;

for ($x = $startLine; $x <= $linesTotal; $x++) {
    $file->seek($x);
    echo $file->current().'<br>';
}

Some test data:

Tamanho do arquivo: 197 MB
Média de tempo de execução: 2.4412620067596 seconds
    
02.09.2015 / 23:50
4

And why not use tail ?

$file = escapeshellarg('tmp.txt');
$rs = 'tail -n 5 $file';
echo $rs;

The test was done in a 2mb file, 92442 lines.

Runtime: 0.107839 (1 millionth of a second)

To confirm the integrity of the performance, the same file was increased by 8 times, 16mb.

The runtime was the same.

Windows 10 Pro 64bit
PHP 5.6.9
Apache 2.4.10
    
03.09.2015 / 03:23
4

Based on the wonderful solution of @DontonMenezes, I developed a class with the tail method to do such an operation.

Let's see:

class FileObject extends SplFileObject {

    public function tail($amount)
    {
        $lastKey = $this->key();

        $this->seek(PHP_INT_MAX);

        $end = $this->key();

        $start = $end - $amount;

        // Set as last Line of iterations 

        $this->seek($lastKey);

        return new LimitIterator($this, $start, $end);
    }
}

The use of this would be:

$f = new FileObject('text.txt');

foreach ($f->tail(5) as $key => $value) {
    echo $value;
}

This results in:

Essa é a linha 9995
Essa é a linha 9996
Essa é a linha 9997
Essa é a linha 9998
Essa é a linha 9999
    
03.09.2015 / 14:07
3

Open the file with the function file and use the function array_slice to get the last 5 lines:

$linhas = file('arquivo.txt');
$linhas = array_slice($linhas, -5);

print_r(implode(PHP_EOL, $linhas));
    
02.09.2015 / 21:53