1

I want to read a file into a string, modify the content and write back the processed string to the file. Also, another request to the server might start too early and try to write the same file before the first is through - that must NEVER happen (so far im using flock) - it would be even better, if the script would be blocking until the lock is released.

Here is some sort of incomplete approach

$h = fopen($fp, 'a+');
flock($h, LOCK_EX);
$oTxt = '';
while (!feof($file)) {
    $oTxt .= fread($h, 8192);
}
rewind($h);
ftruncate($h, 0)
fwrite($h, );    // process contents and write it back
flock($h, LOCK_UN);
fclose($h);

Note: This question is very similar to What's the best way to read from and then overwrite file contents in php? (in my case its a json file i want to decode, insert or edit some node, then encode it again) but its not a duplicate.

Community
  • 1
  • 1
IARI
  • 1,217
  • 1
  • 18
  • 35
  • The fact that you are dealing with json does not seem sufficient to distinguish your question from the one you reference. What are some of the other differences? – gymbrall Jul 20 '15 at 18:38
  • 1
    The questions are essentially the same. The problem with that other question is that none of the answers are good, because they don't really address the locking issue. – Barmar Jul 20 '15 at 18:45
  • Note also, the difference is that I do not want the solution to be the "cleanest" but the most efficient. – IARI Jul 20 '15 at 19:26

1 Answers1

3

You can replace the while loop with a single call to stream_get_contents. And you should use mode r+ to read and write the file; a+ will position the stream at the end of the file when you start, so there won't be anything to read.

$h = fopen($fp, 'r+');
flock($h, LOCK_EX);
$oTxt = stream_get_contents($h);
// Process contents
rewind($h);
ftruncate($h, 0);
fwrite($h, $oTxt); 
flock($h, LOCK_UN);
fclose($h);
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • thx, I didnt use a+ (copypaste error) but w+, which was wrong too ^^ I will give this a shot :) – IARI Jul 20 '15 at 18:58
  • but what if flock returns false? – IARI Jul 20 '15 at 19:00
  • You can add error checking. You should also check whether `fopen()` returns false. If you have access to open the file in write mode, I can't think of why `flock` would fail. – Barmar Jul 20 '15 at 19:02
  • I'm already checking for all those in my actual code (just left that out here to improve readability) But is there a built-in way to make the flock blocking? or do i have to write that including a timeout myself? (you jsut have to love php ... -.-) – IARI Jul 20 '15 at 19:25
  • It's blocking by default, you have to use `LOCK_NB` to make it non-blocking. – Barmar Jul 20 '15 at 19:26
  • It's the same as in C. – Barmar Jul 20 '15 at 19:27