You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDOStatement::rowCount()单次调用先返回行数后返回0的问题

问题分析与解决方案

核心问题拆解

  1. 无效的lastInsertId()调用
    你在UPDATE成功后写了$this->id = $pdo->lastInsertId();,但这个方法只用来获取INSERT操作生成的自增ID,UPDATE根本不会产生新的自增ID,这行代码完全没用,还可能干扰你对逻辑的判断。

  2. rowCount()两次输出的原因
    你dump时看到1和0,说明update()函数被执行了两次:

    • 第一次执行时,数据确实有变化,rowCount返回1;
    • 第二次执行时,提交的字段值和数据库里现有内容完全一致,哪怕WHERE条件匹配,MySQL也不会标记为“修改行”,此时rowCount返回0(哪怕你开了MYSQL_ATTR_FOUND_ROWS,这个参数只保证返回匹配行数而非修改行数,但没有字段变化的话还是会返回0)。

具体修复步骤

1. 删掉无效代码

直接移除$this->id = $pdo->lastInsertId();这一行,你的$this->id已经是WHERE条件里的主键值,不需要重新赋值。

2. 排查函数重复调用

检查调用update()的地方,大概率是重复触发了执行:

  • 在update()开头加一行日志:error_log("update触发,ID: " . $this->id);,看日志里是否有两次相同ID的记录;
  • 检查前端按钮是否绑定了多次点击事件,或者表单是否被重复提交(比如AJAX请求没做防抖)。

3. 可选:调整更新判断逻辑

如果希望只要WHERE条件匹配(哪怕字段没变化)就返回true,可以改成先查是否存在对应行:

// 执行UPDATE
$pdoStatement->execute([...]);

// 检查目标行是否存在
$checkStmt = $pdo->prepare("SELECT 1 FROM album WHERE id = :id");
$checkStmt->execute([':id' => $this->id]);
return $checkStmt->fetch() !== false;

不过这种方式会多一次查询,按需使用即可。

4. 验证PDO参数是否生效

虽然你设置了PDO::MYSQL_ATTR_FOUND_ROWS => true,可以加一行代码确认参数是否真的生效:

$pdo = Database::getPDO();
var_dump($pdo->getAttribute(PDO::MYSQL_ATTR_FOUND_ROWS));

如果输出bool(true)说明参数没问题,否则要检查Database类的getPDO方法是否正确返回了配置好的实例。

修正后的update函数示例

public function update() {
    $pdo = Database::getPDO();
    $sql = "UPDATE `album`
        SET
        title = :title,
        description = :description,
        picture_preview = :picture_preview,
        album_visibility = :album_visibility,
        last_updated = :last_updated
        WHERE id = :id";

    $pdoStatement = $pdo->prepare($sql);
    // 先判断SQL执行是否成功(无语法/权限错误)
    $executeSuccess = $pdoStatement->execute([
        ':title' => $this->title,
        ':description' => $this->description,
        ':picture_preview' => $this->picture_preview,
        ':album_visibility' => $this->album_visibility,
        ':last_updated' => $this->last_updated,
        ':id' => $this->id
    ]);

    if (!$executeSuccess) {
        return false;
    }

    // 返回是否有行被修改
    return $pdoStatement->rowCount() > 0;
}

内容的提问来源于stack exchange,提问作者Manon-PM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:20:14