使用PDO预处理语句报错:PDO::exec()期望参数1为字符串,传入对象
解决PDO预处理语句中的
PDO::exec() expects parameter 1 to be string, object given错误 嘿,这个错误我太熟悉了!你肯定是把PDO预处理生成的PDOStatement对象错传给了exec()方法——这俩完全不是一回事儿,咱们一步步理清楚:
错误根源
PDO::exec()是PDO连接对象的方法,它需要直接传入SQL字符串来执行(比如$db->exec("INSERT INTO ...")),但你现在把prepare()返回的PDOStatement对象(也就是你的$query变量)传给了它,自然会报参数类型不匹配的错误。
而PDO预处理语句的正确执行方式,是调用PDOStatement对象自己的execute()方法,不是exec()!
修正后的代码示例
假设你的INSERT_QUERY是用问号占位符的形式(比如INSERT INTO users (username, email, password) VALUES (?, ?, ?)),修正后的save()方法应该是这样的:
function save() { if ($this->id === null) { // 1. 预处理SQL语句,生成PDOStatement对象 $query = self::$app->db->prepare(self::INSERT_QUERY); // 2. 绑定参数(可选,也可以直接在execute里传数组) $query->bindParam(1, $this->username); $query->bindParam(2, $this->email); $query->bindParam(3, $this->hashedPassword); // 3. 执行预处理语句——用execute(),不是exec()! $isSuccess = $query->execute(); // 如果需要获取插入后的自增ID if ($isSuccess) { $this->id = self::$app->db->lastInsertId(); } return $isSuccess; } else { // 如果是更新用户逻辑,同样用预处理+execute(),示例: $updateQuery = self::$app->db->prepare(self::UPDATE_QUERY); $updateQuery->execute([ $this->username, $this->email, $this->id ]); return $updateQuery->rowCount() > 0; } }
更简洁的写法:直接在execute里传参数数组
你可以跳过手动bindParam,直接把参数数组传给execute(),代码会更简洁:
function save() { if ($this->id === null) { $query = self::$app->db->prepare(self::INSERT_QUERY); // 直接传参数数组,顺序要和占位符对应 $isSuccess = $query->execute([ $this->username, $this->email, $this->hashedPassword ]); if ($isSuccess) { $this->id = self::$app->db->lastInsertId(); } return $isSuccess; } // ... 更新逻辑 }
如果用命名占位符(可读性更好),比如把INSERT_QUERY写成:
INSERT INTO users (username, email, password) VALUES (:username, :email, :password)
那么执行代码可以写成:
$isSuccess = $query->execute([ ':username' => $this->username, ':email' => $this->email, ':password' => $this->hashedPassword ]);
这样不仅避免了SQL注入,还彻底解决了你遇到的参数类型错误~
内容的提问来源于stack exchange,提问作者Nora
相关产品推荐
相关产品推荐

