我正在处理一个动态查询,它使用变量来指定表、字段/列和要搜索的值。我在phpmyadmin(手动键入查询)中以及通过将变量连接到一个完整的查询中,使查询在没有变量的情况下按预期工作。
但是,当我使用 bindParam()
或者 bindValue()
为了绑定变量,它返回一个空数组。
这是我的密码:
function search_db($db, $searchTerm, $searchBy, $searchTable){
try{
$stmt = $db->prepare('
SELECT
*
FROM
?
WHERE
? LIKE ?
');
$stmt->bindParam(1, $searchTable);
$stmt->bindParam(2, $searchBy);
$stmt->bindValue(3, '%'. $searchTerm.'%');
$stmt->execute();
} catch(Exception $e) {
return array();
}
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// database initialization, creates the $db variable
require(ROOT_PATH . "include/database.php");
$matches = search_db($db, 'search term', 'myColumn', 'myTable');
var_dump($matches);
预期结果:数据库中的行数组
实际结果:空数组
1条答案
按热度按时间pkbketx91#
我可以使用pdo prepared语句绑定标识符(表或字段名)或语法关键字吗?
不幸的是,prepared语句只能表示数据文本。所以,一个非常常见的陷阱是这样的查询:
根据pdo设置,此查询将产生错误(在使用实际准备语句的情况下)或文本字符串
'id'
在字段集中(在模拟的情况下)。因此,开发人员必须自己处理标识符—pdo对此没有任何帮助。
要使动态标识符安全,必须遵守两条严格规则:
正确格式化标识符
根据硬编码的白名单进行验证。
要格式化标识符,必须应用以下两条规则:
将标识符括起来。
把背虱翻一番,从里面逃走。
格式化之后,可以安全地将$table变量插入到查询中。所以,代码是:
然而,尽管这样的格式对于order by这样的情况已经足够了,但是对于大多数其他情况,有一种不同类型的注入的可能性:让用户选择他们可以看到的表或字段,我们可能会泄露一些敏感信息,如密码或其他个人数据。所以,最好是对照允许值列表检查动态标识符。下面是一个简单的例子:
对于关键字,规则是相同的,但当然没有可用的格式-因此,只有白名单是可能的,应该使用:
另请参见php文档中的用户贡献注解:pdo::quote上的用户注解