Tuesday, April 16, 2013

How to read a file backward in PHP?

Reading backward means, suppose a text file has 25 lines; and we want to read that file starting from line 25th fist, then line no. 24, then 23rd, 22nd and so on till line number 1.

Check the logic below to achieve this goal. Each line in a text file has a particular position within the file.

a. Start reading the file from the beginning (position zero) and store the current file pointer position into an array. This way, we would store the position of all the lines (starting position) in that array.
b. When reading is complete, we iterate the array backward.
c. For each iteration of that array, we put the file pointer pointing to the array value i.e starting position of a line.

d. Then we read that line and print on screen.

Now check the PHP implementation below.
 

<?php
//// OPEN FILE
$filename = "car_names.txt";
$fp = fopen($filename,"r+")
or
die("Could not open file :: " . error_get_last()['message'] );

//// Create an array to store various positions in the file
$line_beg = array(0);  ///// First line is at position 0

//// Run the loop for reading the file from beginning
while( ($buffer = fgets($fp,80))!== false )
{
  //// Store the starting position of each line to the array
  $line_beg[] = ftell( $fp );   


//// Start iterating the Array backward
for($i = count($line_beg)-1; $i >=0; $i--)
{
  //// Move the file pointer to desired location
  fseek($fp, $line_beg[$i] );
  

  //// Read that line
  $buffer = fgets($fp, 80 );
  if( trim($buffer) != "" )
  {
      //// Print the line
      echo "Line : $i, Content : $buffer<br>";
  }

}

//// Close file
fclose ($fp);
?>


Note :
1. error_get_last() holds various Error related info in array format, hence error_get_last()['message'] points to 'message' key of that array which contains the whole Error message. The whole array looks like as shown below in case the file car_names.txt was not opened successfully ::
 

Array
(
    [type] => 2
    [message] => fopen(car_names.txt): failed to open stream: No such file or directory
    [file] => C:\xampp\htdocs\test.php
    [line] => 2
)


2. $line_beg = array(0);
We initialized the array with the beginning of the first line (position zero)

The code above was really too big when we can do it in only four lines as shown below.

<?php
//// Read Content, create array of all lines in the file
$file = file("$filename");   
//// Reverse the Array
$file = array_reverse($file);
//// Iterate and Print
foreach($file as $f)
{
    echo $f."<br />";
}
?>

No comments: