Для функции поиска я написал запрос MySQL, который будет выполняться скриптом PHP. Я не делаю полнотекстовый поиск. Вместо этого я выполняю поиск, используя следующий метод:
... 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. '[[:>:]]');
а затем использовать эти значения, как в…
... WHERE field LIKE '$wordLike' AND field REGEXP '$wordRX'
что при вводе этого примера приводит к
...
WHERE field LIKE '%2*3\\%5\\_1^0%' AND
field REGEXP '[[:<:]]2\\*3%5_1\\^0[[:>:]]`
Пара замечаний…
LIKE
и REGEXP
вместе -был самым быстрым среди подходов, которые я пробовал.Q1:Это правильный путь?
Q2:Достаточно ли это защищено от SQL-инъекций?
О MySQL REGEXP
…
Следующие символы экранируются с помощью preg _quote()
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
Ниже приведен список [иногда] специальных символов в REGEXP
. \ + * ? [ ^ ] $ ( ) { } | -
. В REGEXP
также есть дополнительные конструкции, но все они заключены в одинарные/двойные скобки, и, поскольку я знаю, что все скобки будут экранированы preg _quote()Я чувствую, что не должен беспокоиться о них.
О MySQL LIKE
…
Единственными двумя специальными символами в LIKE
являются
_ %
. Поэтому побег от них кажется достаточным обходным путем.
Пожалуйста, поправьте меня, если я что-то упустил.