准备用户定义的搜索词以进行查询

inh*_*han 7 php mysql user-input sql-injection escaping

对于搜索功能,我编写了一个由PHP脚本执行的MySQL查询.我没有进行全文搜索.相反,我正在使用以下方法进行搜索:

... WHERE field LIKE '%etc%' AND field REGEXP '[[:<:]]etc[[:>:]]'

现在,我的想法是在PHP中准备这些动态值,例如:

$word = '2*3%5_1^0'; // just an example

$wordLike = strtr($word,array('\\'=>'\\\\','%'=>'\\%','_'=>'\\_'));
// instead of my old solution:
// $wordLike = preg_replace('~([%_])~', '\\\\$1', $word);
$wordLike = $db_con->escape('%' . $wordLike . '%');

$spaces = '[[:blank:]]|[[:punct:]]|[[:space:]]';
// I'm not sure about the difference between blank & space, though

$wordRX = preg_quote($word);
$wordRX = $db_con->escape('(^|'.$spaces.')'.$wordRX.'($|'.$spaces.')');
// instead of my old solution:
// $wordRX = $db_con->escape('[[:<:]]' . $wordRX . '[[:>:]]');
Run Code Online (Sandbox Code Playgroud)

然后使用这些值,如...

... WHERE field LIKE '$wordLike' AND field REGEXP '$wordRX'

通过此示例输入,结果

...
WHERE field LIKE '%2*3\\%5\\_1^0%' AND
field REGEXP '[[:<:]]2\\*3%5_1\\^0[[:>:]]`
Run Code Online (Sandbox Code Playgroud)

几个笔记......

  • 在我的实际代码中,我正在使它处理多个单词,这只是伪代码.
  • 我用来搜索单词的方法 - LIKE和- REGEXP一起 - 是我尝试的方法中最快的方法.
  • 我知道我应该使用PDO,除非与我的问题相关,否则请不要输入任何内容

Q1:这是正确的方法吗?
Q2:这对SQL注入是否足够安全?


一些额外的信息

关于MySQL REGEXP......

以下字符由preg_quote()转义

.\ +*?[^] $(){} =!<> | : -

以下是[偶尔]特殊字符的列表 REGEXP

.\ +*?[^] $(){} | -

还有其他构造,REGEXP但它们都被单 /双括号包围,因为我知道所有括号都将被preg_quote()转义,我觉得我不应该关注它们.

关于MySQL LIKE......

在只有2个特殊字符LIKEARE

_%

所以逃避他们似乎足够的解决方法.
如果我遗漏任何东西,请纠正我.

Chi*_*tan 1

尝试使用mysql_real_escape_string()

$word = '2*3%5_1^0';

$query = 'SELECT * FROM TABLE_NAME WHERE field REGEXP "(.*)[[:<:]]'.mysql_real_escape_string($word).'[[:>:]](.*)" ';
Run Code Online (Sandbox Code Playgroud)