修改后无法从JSON文件获取数据

时间:2019-08-18 11:14:59

标签: php json class oop

我创建了一个类,负责获取和修改JSON文件中的数据。使用添加数据的方法后,获取数据的方法返回null。

JSON表示一个具有两个字段的对象:“最后一个ID”(数字)和“ posts”(帖子数组)(包含字符串的关联数组)。方法“ getPosts()”必须返回帖子数组,方法“ addPost($ post)”必须将新帖子添加到数组。

在这种情况下出现问题:

  1. 我使用getPosts(),效果很好。

  2. 我使用addPost(),它将新帖子添加到JSON。

  3. 如果之后我再次使用getPosts(),它将返回null。

如果我不使用addPost()再次运行脚本,则getPosts()将返回更新的数组。为什么addPost()影响getPosts()的结果?

class PostStorage {
    private $path;

    public function __construct($path) {
        $this->path = $path;
        if (file_exists($path)) return;

        $contents = array(
            "last_id" => 0,
            "posts" => array()
        );
        $this->setStorage($contents);
    }

    public function getPosts() {
        return $this->getStorage()['posts'];
    }

    public function addPost($post) {
        $storage = $this->getStorage();
        $newId = $storage['last_id'] + 1;
        $post['id'] = $newId;

        $storage['posts'][] = $post;
        $storage['last_id'] = $newId;
        $this->setStorage($storage);
    }

    private function setStorage($contents) {
        $handler = fopen($this->path, 'w');
        fwrite($handler, json_encode($contents));
        fclose($handler);
    }

    private function getStorage() {
        $handler = fopen($this->path, 'r');
        $contents = fread($handler, filesize($this->path));
        fclose($handler);
        return json_decode($contents, TRUE);
    }
}

$postStorage = new PostStorage(JSON_PATH);

$post = array(
    "title" => "some title",
    "content" => "some content"
);

echo(json_encode($postStorage->getPosts())); // is fine
$postStorage->addPost($post); // file was modified
echo(json_encode($postStorage->getPosts())); // now it returns null

1 个答案:

答案 0 :(得分:1)

filesize的调用结果被缓存。因此,对filesize中的getStorage的第二次调用返回了旧的大小。因此,仅返回文件的一部分:{"last_id":1,"posts":[{。这将导致json解析器失败并返回一个空数组。此数组没有posts键,因此在getPosts中返回null。

解决方案是先调用clearstatcache();,再调用filesize。 示例代码:

  private function getStorage() {
        clearstatcache();
        $handler = fopen($this->path, 'r');
        $contents = fread($handler, filesize($this->path));
        fclose($handler);

        return json_decode($contents, TRUE);
    }

有关此缓存“功能”的更多信息:https://www.php.net/manual/en/function.clearstatcache.php