【问题标题】:Can't get data from JSON file after modifying it修改后无法从JSON文件中获取数据
【发布时间】:2019-08-19 01:57:44
【问题描述】:

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

JSON 表示具有两个字段的对象:“最后一个 id” - 数字和“帖子” - 帖子数组(包含字符串的关联数组)。方法“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

【问题讨论】:

  • $postStorage->addPost($post);$post 设置在哪里?
  • 对不起,我没有在代码中添加 $post 的初始化,但现在它在这里。此行也在原始脚本中。
  • @kerbholz 抱歉我没早点改

标签: php json class oop


【解决方案1】:

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

解决方案是在调用filesize 之前调用clearstatcache();。 示例代码:

  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

【讨论】:

    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    相关资源
    最近更新 更多