Для функции поиска я написал запрос 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
…
Только 2 специальных символа в LIKE
:
_%
Поэтому избежать их кажется достаточно обходным путем.
Пожалуйста, поправьте меня, если я ничего не пропущу.
Appart из того, что вы упомянули, функция mysql_real_escape_string () должна делать все возможное для дезинфекции от SQL-инъекции.
Вам просто нужно правильно сбежать от любого пользовательского ввода, используя подходящую функцию (ы) экранирования, если вы представляете ее как закодированные блоки обработки, обрабатывающие этот пользовательский ввод, вы будете знать, в каком порядке (от последнего к первому) и что делать с побегом / unescape и когда , и вы должны быть в порядке, если обеспечить чистый ввод (проверка является другой проблемой).
И, как вы уже знаете, цитата () на PDO или Mysqli prepare () – лучший подход.
попробуйте использовать mysql_real_escape_string ()
$word = '2*3%5_1^0'; $query = 'SELECT * FROM TABLE_NAME WHERE field REGEXP "(.*)[[:<:]]'.mysql_real_escape_string($word).'[[:>:]](.*)" ';
function clean($str) { $str = @trim($str); if(get_magic_quotes_gpc()) { $str = stripslashes($str); } return mysql_real_escape_string($str); }
тогда:
$word = clean($_POST['whatever post']);
затем аккуратное слово и ваше добро. то, что делает эта функция php, принимает все литералы и превращает их в строки, поэтому никто не может позволить себе удалить ваш db и т. д.