解决上个文章手滑,导致评论失败的后果

这个问题早在 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