<?php
    
/**
    * o------------------------------------------------------------------------------o
    * | This package is dual licensed as GPL and a commercial license.               |
    * | If you use the code commercially (or if you don't want to be restricted by   |
    * | the GPL license), you will need the commercial license. It's only £49 (GBP - |
    * | roughly $98 depending on the exchange rate) and helps me out a lot. Thanks.  |
    * o------------------------------------------------------------------------------o
    *
    * © Copyright Richard Heyes
    *
    * This simple class allows you to read a file by line as opposed to by byte offset.
    * Quite simple really, as its simply a matter of counting newlines (\n)
    */

    
class LineReader
    
{
        
/**
        * The filename
        */
        
private $filename;
        
        
/**
        * The file handle
        */
        
private $fp;
        
        
/**
        * The line cache
        */
        
private $cache = array();
        
        
/**
        * Whether the cache is enabled
        */
        
private $useCache;
        
        
/**
        * The constructor
        *
        * @param string $filename The filename
        * @param bool   $useCache Whether to use the cache or not
        */
        
public function __construct($filename, $useCache = true)
        {
            
$this->filename = $filename;
            
$this->fp = fopen($filename, 'r');

            if (!
$this->fp) {
                throw new
Exception('Unable to open file: ' . $filename);
            }
            
            
$this->useCache = $useCache;
        }

        
/**
        * Fetches a line from the file
        *
        * @param int $number The line number
        */
        
public function Get($number)
        {
            
/**
            * Line number must be 1 or higher
            */
            
if ($number < 1) {
                throw new
Exception('Line number should be greater than zero');
            }

            
/**
            * Check the line cache first
            */
            
if ($this->isCached($number)) {
                return
$this->cache[$number];
            }

            
/**
            * Reset the file pointer and line number
            */
            
fseek($this->fp, 0);
            
$i = 0;

            
// Get the line
            
while ($i < $number) {
                
$line = fgets($this->fp);
                
$i++;
            }
            
            
$this->cache[$number] = $line;
            
            return
$line;
        }
        
        
/**
        * Returns true/false as to whether a line is cached
        *
        * @param int $number A line number
        */
        
public function isCached($number)
        {
            return
$this->useCache && isset($this->cache[$number]);
        }
    }
?>