PHP - 防止覆盖文件中的数据
PHP - prevent overwriting data in a file
我创建了一个简单的无数据库 CMS。保存文件时,PHP 打开相应的文件,添加新数据,然后关闭文件(使用 file_put_contents)。
这一切都很好 - 直到同一个文件被同时保存两次(或更多次)。我的意思是当一个 file_put_contents 函数在一个已经经历另一个 file_put_contents 函数的文件上启动时。在这种情况下,只有第二个 file_put_contents 的更改会保存到文件中。
所以我的问题是 - 在开始第二个 file_put_contents 之前,有没有一种方法可以检查文件是否已经被写入,并等待它完成写入?file_put_contents?
是的,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。 execute lock.php
in shell 一个保持打开状态,execute put.php
in shell 2 你会看到它在等待,因为独占写锁被获取了该文件的其他脚本。现在回到 shell 并按 Ctrl + c 中止执行(你可以关闭 shell)和回到你的第二个 shell。它应该输出 foo
并且脚本应该终止。
重要
该文件的文件读取未锁定,如果这是要求,请使用 flock
,因为它支持所有操作 (LOCK_SH | LOCK_EX
)。
SQLite
PDO SQLite 将使您能够使用简单的文本文件作为数据库,并为您处理锁定等问题。如果您需要处理大量文件和数据,请考虑使用它,因为它具有开箱即用的所有功能。
我创建了一个简单的无数据库 CMS。保存文件时,PHP 打开相应的文件,添加新数据,然后关闭文件(使用 file_put_contents)。
这一切都很好 - 直到同一个文件被同时保存两次(或更多次)。我的意思是当一个 file_put_contents 函数在一个已经经历另一个 file_put_contents 函数的文件上启动时。在这种情况下,只有第二个 file_put_contents 的更改会保存到文件中。
所以我的问题是 - 在开始第二个 file_put_contents 之前,有没有一种方法可以检查文件是否已经被写入,并等待它完成写入?file_put_contents?
是的,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。 execute lock.php
in shell 一个保持打开状态,execute put.php
in shell 2 你会看到它在等待,因为独占写锁被获取了该文件的其他脚本。现在回到 shell 并按 Ctrl + c 中止执行(你可以关闭 shell)和回到你的第二个 shell。它应该输出 foo
并且脚本应该终止。
重要
该文件的文件读取未锁定,如果这是要求,请使用 flock
,因为它支持所有操作 (LOCK_SH | LOCK_EX
)。
SQLite
PDO SQLite 将使您能够使用简单的文本文件作为数据库,并为您处理锁定等问题。如果您需要处理大量文件和数据,请考虑使用它,因为它具有开箱即用的所有功能。