May 24
解决 Typecho 的评论数据冲突导致的评论失败
解决上个文章手滑,导致评论失败的后果
这个问题早在 17 年初我就踩过了,当时是想转移一条评论来着,结果导致了被转移和转移到的文章评论失败,但是转移的评论可以正常展现
为什么会有这个问题
研究一下 typecho_contents 的结构,有个叫 commentsNum 的 int 字段,因为没仔细读过 Typecho 的源代码,推测应该是作为管理文章或者首页的评论数统计的缓存,每次评论 / 删除评论,把数字 +1 / -1,减轻数据库压力
/** 更新评论数 */
$num = $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num'))->from('table.comments')
->where('status = ? AND cid = ?', 'approved', $comment['cid']))->num;
$this->db->query($this->db->update('table.contents')->rows(array('commentsNum' => $num))
->where('cid = ?', $comment['cid']));
出问题了
这就么简单清晰明了的逻辑,我愣是没找出有什么 bug,也没找到关于验证 commentsNum 的代码,但是它还是有这个奇怪的问题,找到问题的 dalao 快去发 pr(
解决它!
<?php
$conn = new PDO('mysql:host=127.0.0.1;dbname=blog', "root", "");
try {
foreach($conn->query('SELECT * FROM `typecho_contents` WHERE `type` = \'post\' LIMIT 50') as $row) {
echo $row["cid"] . " " . $row["commentsNum"] . " ";
$sql = 'SELECT * FROM `typecho_comments` WHERE `cid` = :cid';
$sth = $conn->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':cid' => $row["cid"]));
$comments = $sth->fetchAll();
echo count($comments) . "\n";
$conn->exec("UPDATE `blog`.`typecho_contents` SET `commentsNum` = " . count($comments) . " WHERE `cid` = " . $row["cid"]);
}
$conn = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
作者:https://blog.lim-light.com/archives/resolution-failed-due-to-conflicting-comments-on-typecho-comment-data.html
:D 少女祈祷中...