我创建了一个类,负责获取和修改JSON文件中的数据。使用添加数据的方法后,获取数据的方法返回null。
JSON表示一个具有两个字段的对象:“最后一个ID”(数字)和“ posts”(帖子数组)(包含字符串的关联数组)。方法“ getPosts()”必须返回帖子数组,方法“ addPost($ post)”必须将新帖子添加到数组。
在这种情况下出现问题:
我使用getPosts(),效果很好。
我使用addPost(),它将新帖子添加到JSON。
如果之后我再次使用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
答案 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