2

I have got a large file in PHP of which I would like to replace the first 512 bytes with some other 512 bytes. Is there any PHP function that helps me with that?

Charles
  • 50,943
  • 13
  • 104
  • 142
hakre
  • 193,403
  • 52
  • 435
  • 836

1 Answers1

10

If you want to optionally create a file and read and write to it (without truncating it), you need to open the file with the fopen() function in 'c+' mode:

$handle = fopen($filename, 'c+');

PHP then has the stream_get_contents() function which allows to read a chunk of bytes with a specific length (and from a specific offset in the file) into a string variable:

$buffer = stream_get_contents($handle, $length = 512, $offset = 0);

However, there is no stream_put_contents() function to write the string buffer back to the stream at a specific position/offset. A related function is file_put_contents() but it does not allow to write to a file-handle resource at a specific offset. But there is fseek() and fwrite() to do that:

$bytes_written = false;
if (0 === fseek($handle, $offset)) {
    $bytes_written = fwrite($handle, $buffer, $length);
}

Here is the full picture:

$handle = fopen($filename, 'c+');
$buffer = stream_get_contents($handle, $length = 512, $offset = 0);

// ... change $buffer ...

$bytes_written = false;
if (0 === fseek($handle, $offset)) {
    $bytes_written = fwrite($handle, $buffer, $length);
}
fclose($handle);

If the length of $buffer is not fixed this will not properly work. In that case it's better to work with two files and to use stream_copy_to_stream() as outlined in How to update csv column names with database table header or if the file is not large it is also possible to do that in memory:

$buffer = file_get_contents($filename);

// ... change $buffer ...

file_put_contents($filename, $buffer);
Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836