将正则表达式绑定到PDO语句中的PDO参数

时间:2011-12-23 21:08:22

标签: php mysql regex pdo

好的,所以我对php和mysql相当新。我正在为mysql数据库创建一个php前端。我正在使用PDO驱动程序来访问数据库,因为它可以防止sql注入攻击。到目前为止,一直没问题,直到我遇到这个问题。我有一个搜索功能,用户可以输入公司名称full或partial来搜索有关它的数据。

这是我用来在数据库中进行搜索的PDO语句:

SELECT CompName FROM CompanyName 
WHERE CompName REGEXP :name 
ORDER BY CompName ASC LIMIT 1

然后我可以准备,将搜索字段中的用户类型绑定到参数名称并执行该语句。只要用户不键入任何元字符,它就可以工作。这是我插入PDO语句而不是名称的非常​​基本的正则表达式:
^ whatusertyped -since最初我正在寻找一个完整的匹配。由于某些公司名称确实包含句点,因此我希望用户能够键入这些字符和我的正则表达式,将它们作为文字而不是元字符。到目前为止,这就是我如何替换元字符以获得字面含义:

用户类型:C。查找以C开头的公司名称。

php函数插入^和\\\\以获得^ C \\。

的输出

mysql获取:^ C \\。并在公司名称的开头搜索C.其中句号是字面意思而不是说"寻找外卡字符"。

所以我正在尝试使用C.因为数据库中有一家公司的名字就是这样开始的,我应该得到一个匹配,但是我不会,PDO语句会返回一个空数组。

我确实尝试过查询:

SELECT CompName FROM CompanyName 
WHERE CompName REGEXP "^C\\\\." 
ORDER BY CompName ASC LIMIT 1

直接在mysql中获得了一个匹配,我也直接在PHP中执行了查询而没有准备,绑定并返回匹配。在我看来,问题在于准备并将搜索词绑定到参数,但我无法弄清楚它究竟是什么以及如何解决它。我真的想使用bind和就像我说的那样准备避免sql注入。

非常感谢任何帮助。希望我能清楚地解释这个问题。

1 个答案:

答案 0 :(得分:4)

我认为您绑定到:name的价值应该只是^C\.,而不是^C\\.。您不需要为 sql 级别进行任何转义,只需要 regex 级别(即\.为文字.

另外,请考虑使用WHERE CompName LIKE 'C.%'。你这里不需要正则表达式。你会这样使用:

function like_escape($s) {
// Do like-expression escaping
    return addcslashes($s, '%_');
}
$searchprefix = 'C.';
$sql = 'SELECT CompName FROM CompanyName WHERE CompName LIKE ? ORDER BY CompName ASC';
$stmt = $db->prepare($sql);
$likeclause = like_escape($searchprefix).'%';
$db->bindValue(1, $likeclause, PDO::PARAM_STR);
$stmt->execute();