PDO执行SHOW COLUMNS触发MySQL 1064语法错误原因及修复咨询
PHP PDO MySQL 1064语法报错分析与修复
报错触发原因
本次报错的根因有两个:
- PDO预处理的参数绑定仅支持值类型的参数占位,表名、列名属于SQL标识符,不能使用
?作为占位符。代码中columnExists方法内的SQL语句SHOW COLUMNS FROM ? LIKE ?将表名设为占位符,绑定时PDO会自动给表名添加单引号,最终生成的非法SQL为SHOW COLUMNS FROM 'dataInjections' LIKE 'type',MySQL不允许表名用单引号包裹,因此触发1064语法错误。 - 原有代码对
execute()返回值的逻辑判断错误:PDOStatement::execute()返回的是布尔值(执行成功返回true,失败返回false),并非查询匹配的行数,原有$count != 0的判断逻辑完全错误,即使SQL语法正确也会得到错误的判断结果。
修复方案
推荐使用更安全的系统表查询实现列存在性校验,无需拼接SQL,所有参数均可安全绑定:
private function columnExists($tblName, $clmnName) { $connection = self::Connection(); // 直接查询INFORMATION_SCHEMA系统表,两个参数均为值类型,可正常使用占位符绑定 $statement = $connection->prepare("SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = ? AND column_name = ?"); $statement->execute([$tblName, $clmnName]); // 直接判断匹配到的列数量是否大于0 return $statement->fetchColumn() > 0; }
如果要保留原有SHOW COLUMNS的写法,需要手动对表名做安全转义后拼接进SQL:
private function columnExists($tblName, $clmnName) { // 对表名做转义处理,添加反引号,避免SQL注入风险 $safeTblName = '`' . str_replace('`', '``', $tblName) . '`'; $connection = self::Connection(); // 表名直接拼入SQL,列名作为值绑定 $statement = $connection->prepare("SHOW COLUMNS FROM $safeTblName LIKE ?"); $execSuccess = $statement->execute([$clmnName]); // 执行成功后通过rowCount判断是否存在匹配列 return $execSuccess && $statement->rowCount() > 0; }
额外优化建议:原有ALTER TABLE语句中的INT(0)写法不规范,INT类型的显示宽度属性已在MySQL 8.0版本废弃,建议改为INT或者INT(11)。
内容的提问来源于stack exchange,提问作者kemal develi
相关产品推荐
相关产品推荐

