Stephen Cheng Stephen Cheng - 4 months ago 13x
PHP Question

File access synchronization with flock in php

I am trying to understand the right way to synchronize file read/write using the flock in PHP.

I have two php scripts.


if (!flock($fp,LOCK_SH))
echo "failed to lock\n";
echo "lock ok\n";
while(true) sleep(1000);


and testwrite.php:

if (flock($fp,LOCK_EX|LOCK_NB))
echo "acquired write lock\n";
echo "failed to acquire write lock\n";

Now I run testread.php and let it hang there. Then I run testwrite.php in another session. As expected, flock failed in testwrite.php. However, the content of the file test.txt is cleared when testwrite.php exits. The fact is, fopen always succeeds even if the file has been locked in another process. If the file is opened with "w" mode, the file content will be erased regardless of the lock. So what is the point of flock here? It doesn't really protect anything.


You are using fopen() with the w mode in testwrite.php. When using the w option fopen() will truncate the file after opening it. (see fopen()).

Because of that the file gets truncated in your example before you try to obtain the exclusive lock. However you'll need an open file descriptor in order to use flock().

The way out of this dilemma is to use a lock file different from the file you are working on. The flock() manual page mentions this:

Because flock() requires a file pointer, you may have to use a special lock file to protect access to a file that you intend to truncate by opening it in write mode (with a "w" or "w+" argument to fopen()).