简体   繁体   中英

PHP - prevent overwriting data in a file

I have created a simple databaseless CMS. When saving a file, the PHP opens the corresponding file, adds the new data, and closes the file (using file_put_contents).

This all works well - until the same file is saved twice (or more) simultaneously. By which I mean when a file_put_contents function is started on a file that is already experiencing another file_put_contents function. In this case, only the changes for the second file_put_contents are saved to the file.

So my question is - is there a way of checking if a file is already being written to, and waiting until it has finished being written to, before starting the second file_put_contents?

Yes, LOCK_EX support was added to file_put_contents in PHP 5.1 which will wait until any other lock on the file is released before writing to it. You can easily test this yourself.

lock.php

#!/usr/bin/env php
<?php

$h = fopen(__DIR__ . DIRECTORY_SEPARATOR . "lock.txt", "c");

register_shutdown_function(function () use ($h) {
    fclose($h);
});

flock($h, LOCK_EX);
while (true);

put.php

#!/usr/bin/env php
<?php

$f = __DIR__ . DIRECTORY_SEPARATOR . "lock.txt";

file_put_contents($f, "foo", LOCK_EX);

echo file_get_contents($f) , PHP_EOL;

Test

Put both scripts in the same directory and open two shells. Execute lock.php in shell one and keep it open, execute put.php in shell two and you'll see that it is waiting, because an exclusive write lock was acquired by the other script for the file. Now go back to shell one and hit Ctrl + c to abort execution (you may close the shell) and go back to your second shell. It should output foo and the script should terminate.

Important

Reading of the file is not locked for this file, if this is a requirement use flock since it supports all operations ( LOCK_SH | LOCK_EX ).

SQLite

PDO SQLite would give you the ability to work with simple text files as your database and take care of problems like locking for you. If you need to work with a lot of files and data consider using it as it features everything you need out of the box.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM