PHP - 防止覆盖文件中的数据

时间:2015-01-12 11:50:57

标签: php file overwrite

我创建了一个简单的无数据库CMS。保存文件时,PHP会打开相应的文件,添加新数据并关闭文件(使用file_put_contents)。

这一切都很有效 - 直到同一文件同时保存两次(或更多)。我的意思是在已经遇到另一个file_put_contents函数的文件上启动file_put_contents函数时。在这种情况下,只将第二个file_put_contents的更改保存到文件中。

所以我的问题是 - 在启动第二个file_put_contents之前,有没有办法检查文件是否已被写入,并等待它完成写入?

1 个答案:

答案 0 :(得分:1)

是的,LOCK_EX支持已添加到PHP 5.1中的file_put_contents,它将等到文件上的任何其他锁定被释放后再写入它。您可以自己轻松测试。

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;

测试

将两个脚本放在同一目录中并打开两个shell。在shell 1中执行lock.php并保持打开状态,在shell 2中执行put.php,您将看到它正在等待,因为该文件的另一个脚本获取了独占写锁。现在返回shell shell并点击 Ctrl + c 中止执行(你可以关闭shell)并返回到你的第二个shell。它应该输出foo并且脚本应该终止。

重要

对于此文件,未锁定对该文件的读取,如果这是一项要求,请使用flock,因为它支持所有操作(LOCK_SH | LOCK_EX)。

的SQLite

PDO SQLite将使您能够使用简单的文本文件作为数据库,并处理锁定等问题。如果您需要处理大量文件和数据,请考虑使用它,因为它具有开箱即用的所有功能。