PHP Simultaneous File Writes

后端 未结 5 1777
后悔当初
后悔当初 2020-12-09 09:03

I have two different PHP files that both write to the same file. Each PHP script is called by a user action of two different HTML pages. I know it will be possible for the t

相关标签:
5条回答
  • 2020-12-09 09:30

    The usual way of addressing this is to have both scripts use flock() for locking:

    $f = fopen('some_file', 'a');
    flock($f, LOCK_EX);
    fwrite($f, "some_line\n");
    flock($f, LOCK_UN);
    fclose($f);
    

    This will cause the scripts to wait for each other to get done with the file before writing to it. If you like, the "less important" script can do:

    $f = fopen('some_file', 'a');
    if(flock($f, LOCK_EX | LOCK_NB)) {
        fwrite($f, "some_line\n");
        flock($f, LOCK_UN);
    }
    fclose($f);
    

    so that it will just not do anything if it finds that something is busy with the file.

    0 讨论(0)
  • Take a look at the flock function.

    0 讨论(0)
  • 2020-12-09 09:41

    Please note:

    As of PHP 5.3.2, the automatic unlocking when the file's resource handle is closed was removed. Unlocking now always has to be done manually.

    The updated backward compatible code is:

    if (($fp = fopen('locked_file', 'ab')) !== FALSE) {
        if (flock($fp, LOCK_EX) === TRUE) {
            fwrite($fp, "Write something here\n");
            flock($fp, LOCK_UN);
        }
    
        fclose($fp);
    }
    

    i.e. you have to call flock(.., LOCK_UN) explicitly because fclose() does not do it anymore.

    0 讨论(0)
  • 2020-12-09 09:47

    Please note posix states atomic access if files are opened as append. This means you can just append to the file with several threads and they lines will not get corrupted.

    I did test this with a dozen threads and few hundred thousand lines. None of the lines were corrupted.

    This might not work with strings over 1kB as buffersize might exceed.

    This might also not work on windows which is not posix compliant.

    0 讨论(0)
  • 2020-12-09 09:52

    FYI: flock only works on *nix and is not available on Windows

    0 讨论(0)
提交回复
热议问题