Is this the most efficient way to get and remove first line in file?

There is no more efficient way to do this other than rewriting the file.


No need to create a second temporary file, nor put the whole file in memory:

if ($handle = fopen("file", "c+")) {             // open the file in reading and editing mode
    if (flock($handle, LOCK_EX)) {               // lock the file, so no one can read or edit this file 
        while (($line = fgets($handle, 4096)) !== FALSE) { 
            if (!isset($write_position)) {        // move the line to previous position, except the first line
                $write_position = 0;
            } else {
                $read_position = ftell($handle); // get actual line
                fseek($handle, $write_position); // move to previous position
                fputs($handle, $line);           // put actual line in previous position
                fseek($handle, $read_position);  // return to actual position
                $write_position += strlen($line);    // set write position to the next loop
            }
        }
        fflush($handle);                         // write any pending change to file
        ftruncate($handle, $write_position);     // drop the repeated last line
        flock($handle, LOCK_UN);                 // unlock the file
    }
    fclose($handle);
}

I came up with this idea yesterday:

function read_and_delete_first_line($filename) {
  $file = file($filename);
  $output = $file[0];
  unset($file[0]);
  file_put_contents($filename, $file);
  return $output;
}

This will shift the first line of a file, you dont need to load the entire file in memory like you do using the 'file' function. Maybe for small files is a bit more slow than with 'file' (maybe but i bet is not) but is able to manage largest files without problems.

$firstline = false;
if($handle = fopen($logFile,'c+')){
    if(!flock($handle,LOCK_EX)){fclose($handle);}
    $offset = 0;
    $len = filesize($logFile);
    while(($line = fgets($handle,4096)) !== false){
        if(!$firstline){$firstline = $line;$offset = strlen($firstline);continue;}
        $pos = ftell($handle);
        fseek($handle,$pos-strlen($line)-$offset);
        fputs($handle,$line);
        fseek($handle,$pos);
    }
    fflush($handle);
    ftruncate($handle,($len-$offset));
    flock($handle,LOCK_UN);
    fclose($handle);
}

Tags:

Php

File