安全的PHP JSON日志记录


Safe PHP JSON logging

我正在使用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);
?>