View last 5 lines of a PHP file?

Asked

Viewed 1,277 times

5

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

Thus:

> tail -n 5 public/index.php 

I would like to do the same thing in PHP. But I didn’t want to load the whole file, but really only display the last 5 lines.

I know it’s possible to display the first five 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?

Observing: I don’t want a solution where you have to open the command line via PHP.

  • 1

    :I hope there’s an easy way to do this.

  • performance or performance?

  • Eiu always getting confused.

4 answers

4


The best performance solution I could come up with 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 data from the test:

Tamanho do arquivo: 197 MB
Média de tempo de execução: 2.4412620067596 seconds

4

And why not use the tail?

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

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

Execution time: 0.107839 (1 millionth of a second)

To confirm performance integrity, the same file has been increased by 8 times, 16mb.

The running time was the same.

Windows 10 Pro 64bit
PHP 5.6.9
Apache 2.4.10
  • Answer: Why you can’t do this on shared servers.

  • -1 As stated in the question itself, I would not like solutions that use the command line.

  • These types of simple commands that do not affect the security of the environment at all are usually released even on shared servers. Command line is not synonymous with security breach.

  • but what a reason to give a negative huh... rsrs

4

Based on @Daltonmenezes' wonderful solution, I developed a class with the method tail, to perform 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

3

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

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

print_r(implode(PHP_EOL, $linhas));
  • 1

    +1 I thought this solution was cool, but is there any way that the other lines do not enter the processing for the sake of memory saving. I mean, imagine a file of 50MB...

  • The function file return all lines of the file in one array, that’s not it?

  • That’s right. I’m seeing a more practical solution.

  • I had thought to use new LimitIterator(new SplFileObject()). But how will I know the "limit" since in PHP there is no way to know which is the last line!?!?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.