Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Since this answer is long, here's the summary: <em>No, <code>file_get_contents()</code> is not atomic as it does not respect advisory locks</em>.</p> <h2>About file locks in PHP:</h2> <p>In PHP, while on a *nix platform, filesystem locking is advisory only. Per <a href="http://php.net/manual/en/function.flock.php" rel="nofollow noreferrer">the docs</a> (Emphasis mine):</p> <blockquote> <p>PHP supports a portable way of locking complete files in an advisory way (which means all <strong>accessing programs have to use the same way of locking or it will not work</strong>). By default, this function will block until the requested lock is acquired; this may be controlled (on non-Windows platforms) with the LOCK_NB option documented below.</p> </blockquote> <p>So, as long as all of the processes that are accessing the file use this method of locking, you're fine.</p> <p>However, if you're writing a static HTML file with a sane webserver, the lock will be ignored. In the middle of the write, if a request comes in, Apache will serve the partially written file. The locks will have no effect on the other process reading the lock.</p> <p>The only real exception is if you use the special mount option of <code>-o mand</code> on the filesystem to enable mandatory locking (but that's not really used much, and can have a performance penalty).</p> <p>Have a read on <a href="http://en.wikipedia.org/wiki/File_locking" rel="nofollow noreferrer">File Locking</a> for some more information. Namely the section under <em>Unix</em>:</p> <blockquote> <p>This means that cooperating processes may use locks to coordinate access to a file among themselves, but programs are also free to ignore locks and access the file in any way they choose to.</p> </blockquote> <p>So, in conclusion, using <code>LOCK_EX</code> will create an advisory lock on the file. Any attempt to read the file will block only if the reader respects and/or checks for the lock. If they do not, the lock will be ignored (since it can be). </p> <p>Try it out. In one process:</p> <pre><code>file_put_contents('test.txt', 'Foo bar'); $f = fopen('test.txt', 'a+'); if (flock($f, LOCK_EX)) { sleep(10); fseek($f, 0); var_dump(fgets($f, 4048)); flock($f, LOCK_UN); } fclose($f); </code></pre> <p>And while it's sleeping, call this:</p> <pre><code>$f = fopen('test.txt', 'a+'); fwrite($f, 'foobar'); fclose($f); </code></pre> <p>The output will be <code>foobar</code>...</p> <h2>About <code>file_get_contents</code> specifically:</h2> <p>To your other specific question, first off, there is no <code>LOCK_EX</code> parameter to <a href="http://us.php.net/manual/en/function.file-get-contents.php" rel="nofollow noreferrer"><code>file_get_contents</code></a>. So you can't pass that in.</p> <p>Now, looking at the <a href="https://github.com/php/php-src/blob/master/ext/standard/file.c#L521" rel="nofollow noreferrer">source code</a>, we can see the function <code>file_get_contents</code> defined on line 521. There are no calls to the internal function <code>php_stream_lock</code> as there are when you pass <code>file_put_contents('file', 'txt', LOCK_EX);</code> defined on line 589 of the same file.</p> <p>So, let's test it, shall we:</p> <p>In file1.php:</p> <pre><code>file_put_contents('test.txt', 'Foo bar'); $f = fopen('test.txt', 'a+'); if (flock($f, LOCK_EX)) { sleep(10); fseek($f, 0); var_dump(fgets($f, 4048)); flock($f, LOCK_UN); } fclose($f); </code></pre> <p>In file2.php:</p> <pre><code>var_dump(file_get_contents('test.txt')); </code></pre> <p>When run, <code>file2.php</code> returns immediately. So no, it doesn't appear that <code>file_get_contents</code> respects file locks at all...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload