php - 在查询中使用 REGEX 准备的 SQL 语句的安全性

标签 php mysql pdo

<分区>

我正在尝试使用准备好的 PDO 语句用于如下所示的数据库查询,其中占位符变量由引号中的数字表示,即“123”和“456”:

SELECT `user_ID` as `ID` 
FROM `usermeta` 
WHERE (`meta_key` = 'custom_fields') 
AND (`meta_value` REGEXP '.*"ABC";.*s:[0-9]+:"123".*') 
AND (`meta_value` REGEXP '.*"DEF";.*s:[0-9]+:"456".*')

我的问题是,最佳做法是绑定(bind)到整个 REGEX 表达式,还是仅绑定(bind)到“123”和“456”变量(在 REGEX 表达式中甚至可能),还是完全不同的东西?

换句话说,这是首选:

SELECT `user_ID` as `ID` 
FROM `usermeta` 
WHERE (`meta_key` = 'custom_fields') 
AND (`meta_value` :REGEXP1) 
AND (`meta_value` :REGEXP2)

$stmt->bindParam(':REGEXP1', "REGEXP '.*"ABC";.*s:[0-9]+:"123".*'");
$stmt->bindParam(':REGEXP2', "REGEXP '.*"DEF";.*s:[0-9]+:"456".*'");

还是这个? (我知道在占位符周围使用双引号会有一些问题。)

SELECT `user_ID` as `ID` 
FROM `usermeta` 
WHERE (`meta_key` = 'custom_fields') 
AND (`meta_value` REGEXP '.*"ABC";.*s:[0-9]+:":value1".*') 
AND (`meta_value` REGEXP '.*"DEF";.*s:[0-9]+:":value2".*')

$stmt->bindParam(':value1', '123');
$stmt->bindParam(':value2', '456');

谢谢。

最佳答案

占位符不能被引用。就这么简单:

SELECT ... WHERE foo = ?
SELECT ... WHERE foo = '?'

第一个是占位符,按预期工作。另一个是测试与字符“问号”的相等性。它不再是占位符。

还有 ? 也是正则表达式元字符的问题。如果可以引用占位符,则给出

SELECT ... WHERE foo REGEXP '^.?' 

? 是查询占位符,还是正则表达式“零或一”范围运算符?

如果你想在正则表达式中使用占位符,你必须“构建”正则表达式模式

SELECT ... WHERE foo REGEXP concat('^.', ?)

与构建 LIKE 模式的方式完全相同:

SELECT ... WHERE foo LIKE '%?%' // wrong
SELECT ... WHERE foo LIKE concat('%', ?, '%') // right

关于php - 在查询中使用 REGEX 准备的 SQL 语句的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39171717/

相关文章:

mysql - 检查一个字段的值是否在另一个字段中

MySQL COALESCE 有两个参数?

php - 使用类时查询速度慢

php - 使用 PHP/MySql 中的单个查询从多个表中获取 'related' 数据?

php - 我可以使用 php artisan db :seed to seed related tables?

php - 如何使用 Facebook 作为我网站的网关

php - 在父进程中杀死僵尸子进程

php - ZF2 日期之间

mysql - TINYINT 列值切换为 true 和 1

PHP PDO 清理变量