freddiefujiwara
freddiefujiwara

Reputation: 59089

Can I replace and read simultaneously?

I have a file and I don't wanna take a copy from this file.

so I'd like to replace and read simultaneously in PHP5;

In my head , The code will be the following :

<?php
$fp = fopen('text', 'rw');
while (!feof($fp)) {
  $line = fgets($fp);
  $line = "CONVERTED";
  fprintf($fp,$line);
}
fclose($fp);

Upvotes: 1

Views: 444

Answers (1)

Vegard Larsen
Vegard Larsen

Reputation: 13047

Yes you can conceptually, but it will be difficult if you are replacing content with content of a different length.

fgets and fprintf work by working with a file pointer. The pointer is basically where you are in the file. Both using fgets and fprintf will advance that pointer. Consider this representation of a short file (> is the pointer) right after it has been opened:

>First line
 Second line
 Third line

Then you run your first fgets, which reads the line and moves the pointer:

 First line
>Second line
 Third line

Now if you try to write to the file, it will write where the pointer is; overwriting the content. So say you changed "First line" to "Foobar", and try to write immediately following the fgets call (as in your code), this will be the result:

 First line
 Foobar> line
 Third line

Note that the pointer is now in the middle of the line.

If you however rewind the pointer before you use fprintf, it will print in the right place:

<?php
$fp = fopen('text', 'rw');
while (!feof($fp)) {
  $line = fgets($fp);
  fseek($fp, -strlen($line), SEEK_CUR);
  // length has to be identical to string you replaced
  $line = "FoobarLine"; 
  fprintf($fp,$line);
}
fclose($fp);
?>

Note that this will NOT work if your replacement lines differ in size from the original, as it will then overwrite data it should not, or start reading at the wrong place.


Better solutions would be:

  • If the file is small enough; use file to load it line by line, modify the array to your liking, and overwrite it using file_put_contents(implode("\n", $array).
  • Simply use a temporary file. Not a big deal.

Upvotes: 3

Related Questions