phpfilerandom-access

Random access file in PHP


Is there some PHP function or class that allows me to read a file like an array of characters?

For example:

$string = str_split('blabla');

$i = 0;

switch($string[$i]){

  case 'x':
    do_something();
    $i++;


  case 'y':
    if(isset($string[++$i]))
      do_something_else();
    else
      break;

   case 'z':
      // recursive call of this code etc..

}

I know that I can use $string = file_get_contents($file), but the problem is that I get a huge amount of memory used for a tiny 800K file (like 80MB).

So can I somehow "stream" the file in my code above with some kind of arrayaccess like class that automatically reads data from the file when I call isset() ? :)


Solution

  • You can use fseek and fgetc to jump around in a file and read single characters at a time.

    // Leaves the file handle modified
    function get_char($file, $char) {
       fseek($file, $char);
       return fgetc($file);
    }
    

    You mentioned you wanted array behavior specifically. You can build a class which implements ArrayAccess to support this.

    This could be dangerous for several reasons:


    A slightly more efficient alternative would be to "lazily" read the file (i.e., read it in chunks rather than all at once). Here's some (untested) code:

    class BufferedReader {
        // The size of a chunk in bytes
        const BUFFER_SIZE = 512;
    
        protected $file;
        protected $data;
    
        function __construct($fname) {
            $this->file = fopen($fname, 'r');
        }
    
        function read_buffer() {
            $this->data .= fread($this->file, self::BUFFER_SIZE);
        }
    
        function get_char($char) {
            while ( $char >= strlen($this->data) && !feof($this->file) ) {
                $this->read_buffer();
            }
    
            if ( $char >= strlen($this->data) ) {
                return FALSE;
            }
    
            return substr($this->data, $char, 1);
        }
    }