我正在使用JSON作为数据存储,随着时间的推移,我预计几方可能希望在短时间内像聊天日志一样写入我的JSON文件。
<?php
$foo = json_decode(file_get_contents("foo.json"), true);
if (! is_array($foo["bar"])) { $foo["bar"] = array(); }
array_push($foo["bar"], array("time" => time(), "who" => $_SERVER['REMOTE_ADDR'], msg => $_GET['m']));
file_put_contents("foo.json", json_encode($foo, JSON_PRETTY_PRINT));
?>
所以上面的代码是有效的,但我担心如果文件在写出来之前被读取,或者在某些情况下他们同时写出来,导致一些数据丢失,会发生什么?
什么是更好或更安全的设计,最好使用平面文件存储(即不是数据库)?
至于奖金,我真的不想回到我的客户那里,他提出了一些"锁定"的请求。理想情况下,请求是等待安全返回。
您可以为此使用flock()
函数。它所做的是为除当前进程之外的所有进程锁定文件。
http://php.net/manual/en/function.flock.php
基本用途:
<?php
$fp = fopen('path/to/data.json', 'r+');
if (flock($fp, LOCK_EX)) // locks the file
{
// write to the file
flock($fp, LOCK_UN); // remove the lock
}
fclose($fp);
默认情况下,flock()
处于阻塞状态。这意味着进程正在等待,直到它获得访问锁的权限。看看关于如何实现非阻塞版本的文档。
如何为每一行创建单独的JSON,这样就不需要每次都加载JSON。您只需将JSON附加到文件中。每个乔森都将在一行。
当您加载它时,您将读取文本文件中的每一行,然后在PHP中将其转换为Json。
我之所以推荐这种方式,是因为我们想找到其他方法来获得更好的文件读写解决方案//http://php.net/manual/en/function.file-put-contents.phpfile_put_contents("foo.json",json_encode($foo,json_PRETTY_PRINT)。JSON只是一种文本格式。所以我相信这是一个很好的解决方案。
写入
<?php
$_SERVER['REMOTE_ADDR'], msg => $_GET['m']));
$foo = array("time" => time(), "who" => $_SERVER['REMOTE_ADDR'], msg => $_GET['m']);
//http://php.net/manual/en/function.file-put-contents.php
file_put_contents("foo.json", json_encode($foo, JSON_PRETTY_PRINT), FILE_APPEND | LOCK_EX));
?>
正如您所提到的,它是一个日志,所以您可能不需要加载就可以一直看到它。所以我们将专注于写作。阅读可能是一个漫长的过程。读取
<?php
$log_array = array();
$handle = @fopen("foo.json", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
$foo = json_decode($buffer, true);
$log_array[] = $foo;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail'n";
}
fclose($handle);
}
print_r($log_array);
?>