31

I know file_put_contents() makes it really easy to append data to a file in PHP. I'd like to try using PHP "threads" to file_put_contents() to the same log file from different PHP threads. Is there a risk in running file_put_contents() on the same file from different PHP threads or will these threads happily block if the file is locked or being accessed by another thread?

EDIT: Found a similar question that recommends flock(), but the risk question does not seem to be fully addressed. Are these "atomic" write operations?

Community
  • 1
  • 1
buley
  • 28,032
  • 17
  • 85
  • 106

2 Answers2

30

as it says on the man page (that you gave a link for!):

// Write the contents to the file, 
// using the FILE_APPEND flag to append the content to the end of the file
// and the LOCK_EX flag to prevent anyone else writing to the file at the same time
file_put_contents($file, $person, FILE_APPEND | LOCK_EX);

Use the LOCK_EX flag to prevent double writes

Naftali
  • 144,921
  • 39
  • 244
  • 303
  • 13
    One thing is not very clear here (to me at least) -- It is clear that using the `LOCK_EX` flag no one will intervene while you are writing. But at what cost to them? What if one of your main concerns is success of that *anyone else*? Is it safe to assume the other thread will wait for the lock to be removed and succeed in their write? – Majid Fouladpour Feb 18 '14 at 21:34
  • 1
    [flock](http://www.php.net/manual/en/function.flock.php) is used for the locking. By default the function will block until the the lock is acquired, and since `file_put_contents` provides no way to specify anything else, I assume it will just block here too. – Jasper Feb 19 '14 at 01:07
  • 3
    And to clear things up: it is an advisory lock. Only when the other thread uses the same kind of locking will this work, and thus it's valid that someone calling *this function* (or something else based on the same locking system) will block (on this call). Anyone else not going through hoops to respect this lock will be able to ignore it entirely and won't magically have to wait or something like that. – Jasper Feb 19 '14 at 01:12
  • What about other fpm-workers for instance? As I understand the docs of flock: `Warning: On some operating systems flock() is implemented at the process level. When using a multithreaded server API you may not be able to rely on flock() to protect files against other PHP scripts running in parallel threads of the same server instance!` I don't think you can rely on LOCK_EX in every situation. – LeoRado May 11 '23 at 09:33
4

Simple answer, yes. clashes can occur

use something like file_put_contents($location, $data, FILE_APPEND | LOCK_EX);

When you expect multiple instances to write to the same file, you should acquire an exclusive lock so no other processes can write to the file until the current one has finished writing it's data

Jase
  • 599
  • 3
  • 9