Read file lines backwards (fgets) with php
Asked Answered
A

5

10

I have a txt file that I want to read backwards, currently I'm using this:

$fh = fopen('myfile.txt','r');
while ($line = fgets($fh)) {
  echo $line."<br />";
}

This outputs all the lines in my file.
I want to read the lines from bottom to top.

Is there a way to do it?

Attend answered 13/12, 2013 at 7:44 Comment(0)
T
16

First way:

$file = file("test.txt");
$file = array_reverse($file);
foreach($file as $f){
    echo $f."<br />";
}

Second Way (a):

To completely reverse a file:

$fl = fopen("\some_file.txt", "r");
for($x_pos = 0, $output = ''; fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
    $output .= fgetc($fl);
    }
fclose($fl);
print_r($output);

Second Way (b): Of course, you wanted line-by-line reversal...


$fl = fopen("\some_file.txt", "r");
for($x_pos = 0, $ln = 0, $output = array(); fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos--) {
    $char = fgetc($fl);
    if ($char === "\n") {
        // analyse completed line $output[$ln] if need be
        $ln++;
        continue;
        }
    $output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : '');
    }
fclose($fl);
print_r($output);

Trapeziform answered 13/12, 2013 at 7:49 Comment(1)
mode 'a+' moves cursor at the end of the file for you :) (but there is a bug that the cursor is moved after first I/O, not immediatly)Paregmenon
E
4

Try something simpler like this..

print_r(array_reverse(file('myfile.txt')));
Extinct answered 13/12, 2013 at 7:45 Comment(0)
P
4

Here is my solution for just printing the file backwards. It is quite memory-friendly. And seems more readable (IMO [=in my opinion]).

It goes through the file backwards, count the characters till start of a line or start of the file and then reads and prints that amount of characters as a line, then moves cursor back and reads another line like that...

  if( $v = @fopen("PATH_TO_YOUR_FILE", 'r') ){ //open the file
    fseek($v, 0, SEEK_END); //move cursor to the end of the file
    /* help functions: */
    //moves cursor one step back if can - returns true, if can't - returns false
    function moveOneStepBack( &$f ){ 
      if( ftell($f) > 0 ){ fseek($f, -1, SEEK_CUR); return true; }
        else return false;
    }
    //reads $length chars but moves cursor back where it was before reading 
    function readNotSeek( &$f, $length ){ 
      $r = fread($f, $length);
      fseek($f, -$length, SEEK_CUR);
      return $r;  
    }

    /* THE READING+PRINTING ITSELF: */
    while( ftell($v) > 0 ){ //while there is at least 1 character to read
      $newLine = false;
      $charCounter = 0;

      //line counting
      while( !$newLine && moveOneStepBack( $v ) ){ //not start of a line / the file
        if( readNotSeek($v, 1) == "\n" ) $newLine = true;
        $charCounter++;              
      } 

      //line reading / printing
      if( $charCounter>1 ){ //if there was anything on the line
        if( !$newLine ) echo "\n"; //prints missing "\n" before last *printed* line            
        echo readNotSeek( $v, $charCounter ); //prints current line  
      }   

    }
    fclose( $v ); //close the file, because we are well-behaved
  }

Of course replace PATH_TO_YOUR_FILE with your own path to your file, @ is used when opening the file, because when the file is not found or can't be opened - warning is raised - if you want to display this warning - just remove the error surpressor '@'.

Paregmenon answered 27/10, 2014 at 19:15 Comment(2)
Thanks. I think this is the best solution.Purplish
Sidenote: this is memory-friendly for a decent amount of characters per line :)Paregmenon
R
2

If the file is not so big you can use file():

$lines = file($file);
for($i = count($lines) -1; $i >= 0; $i--){
    echo $lines[$i] . '<br/>';
}

However, this requires the whole file to be in memory, that's why it is not suited for really large files.

Roesch answered 13/12, 2013 at 7:47 Comment(0)
P
0

Here's my simple solution without messing up anything or adding more complex code

$fh = fopen('myfile.txt','r');
while ($line = fgets($fh)) {
  $result = $line . "<br>" . $result;
}
echo $result // or return $result if you are using it as a function
Pathognomy answered 21/2, 2021 at 7:32 Comment(1)
It's not going to read the file in reverse as the author asksChippewa

© 2022 - 2024 — McMap. All rights reserved.