描述表时的 PDO 异常



我收到错误:

SQLSTATE[42000]:语法错误或访问冲突:1064 您有一个 您的 SQL 语法错误;检查与您的手册相对应的手册 MySQL 服务器版本,用于在"mytable"附近使用的正确语法 第 1 行

当我使用

$fields = Table::getFieldsForTable('mytable');

如果我硬编码:t到我的表名,那么代码可以很好地执行。

public static function getFieldsForTable ($table ) {
$sql = 'DESCRIBE :t';
try {
/**
* @var $db PDO
*/
$db = static::getDB();
$stmt = $db->prepare($sql);
$stmt->bindValue(':t', $table, PDO::PARAM_STR);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e){
echo "PDO ERROR" . $e->getMessage();
}
}

我在项目的其他部分一遍又一遍地使用相同的代码片段,但我没有看到我在这里做错了什么。

有什么帮助吗?

仅仅因为表或列名不能被PDO中的参数替换 - 这只是其工作方式的基本限制。

查看重复问题的答案: PHP PDO 语句可以接受表或列名作为参数吗?

https://stackoverflow.com/a/15990488/180733 是一个很好的解释。

如果您担心接受任意表名的安全性,请考虑使用SHOW TABLES预先获取所有表名,然后使用in_array ($table, $tables)根据该列表验证建议的表名。

bindValuePDO::FETCH_ASSOC引号将字符串括起来,就好像它是您用于插入或选择等的值一样。只需连接字符串

$sql="DESCRIBE ".$table;. 

为了安全起见,开发一个仅检测有效表名的正则表达式,例如像这样的东西

preg_match('/^[a-zA-Z]{1}[a-zA-Z_]{1,18}$/',$table);

或与白名单匹配,例如接受的表数组