我收到错误:
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)
根据该列表验证建议的表名。
bindValue
用PDO::FETCH_ASSOC
引号将字符串括起来,就好像它是您用于插入或选择等的值一样。只需连接字符串
$sql="DESCRIBE ".$table;.
为了安全起见,开发一个仅检测有效表名的正则表达式,例如像这样的东西
preg_match('/^[a-zA-Z]{1}[a-zA-Z_]{1,18}$/',$table);
或与白名单匹配,例如接受的表数组