Porto

Read Line From File

Read Line From File

Reading files in PHP can be a tricky business if not handled correctly. Most often when confronted with reading a line from, the nearest tool to hand is the file() function. The problem with using the file() function is that it reads the whole file into an array, and thus, into memory. Any subsequent operations on the array, such as foreach() result in an internal copy of the array for PHP to work on. Should the file be a two gig log file, then the result could be up to four gigs worth of memory being devoured to gain a few hundred k of text.

A better, and more efficient way is to loop through the file stream using the stream_get_line() function. Care still needs to be taken to clear the buffer on each iteration, or the same problem could potentially arise as with the file() method.

By using this method of looping through the file, and breaking when the appropriate line is found, memory usage is minimized to only a single line of the file. Should one hundred users access this at the same time, no issues will arise as when each user could be using up to four gig each.


<?php

/**
 *
 * Read a line number from a file
 *
 * @param    string    $file    The path to the file
 * @param    int    $line_num    The line number to read
 * @param    string    $delimiter    The character that delimits lines
 * @return    string    The line that is read
 *
 */
function readLine($file$line_num$delimiter="\n")
{
    
/*** set the counter to one ***/
    
$i 1;

    
/*** open the file for reading ***/
    
$fp fopen$file'r' );

    
/*** loop over the file pointer ***/
    
while ( !feof $fp) )
    {
        
/*** read the line into a buffer ***/
        
$buffer stream_get_line$fp1024$delimiter );
        
/*** if we are at the right line number ***/
        
if( $i == $line_num )
        {
            
/*** return the line that is currently in the buffer ***/
            
return $buffer;
        }
        
/*** increment the line counter ***/
        
$i++;
        
/*** clear the buffer ***/
        
$buffer '';
    }
    return 
false;
}
?>

Example Usage


<?php

/*** make sure the file exists ***/
$file 'my_file.txt';

if( 
file_exists$file ) && is_readable$file ) )
{
    echo 
readLine($file6);
}
else
{
    echo 
"Cannot read from $file";
}
?>

This method of iterating over the file and seeking to the line number works well and is memory efficient, but it would be nice to have PHP do the work for us. PHP provides the SPL File Object which will do exactly what is required.


<?php

/*** the file to read ***/
$file 'foo.txt';

        
/**
 *
 * Read a line number from a file
 *
 * @param    string    $file    The path to the file
 * @param    int    $line_num    The line number to read
 * @return    string    The line that is read
 *
 */
function readLine$file$line_number )
{
        
/*** read the file into the iterator ***/
        
$file_obj = new SplFileObject$file );

        
/*** seek to the line number ***/
        
$file_obj->seek$line_number );

        
/*** return the current line ***/
        
return $file_obj->current();
}

echo 
readLine$file345678 );

?>