Полный текстовый поиск SQL с PHP и PDO

Я пытаюсь написать простой, полный текстовый поиск с PHP и PDO. Я не совсем уверен, что лучший способ – искать БД через SQL и PDO. Я нашел этот скрипт, но это старое расширение MySQL. Я написал эту функцию, которая должна рассчитывать совпадения поиска, но SQL не работает. Строка входящего поиска выглядит так: 23+more+people

 function checkSearchResult ($searchterm) { //globals global $lang; global $dbh_pdo; global $db_prefix; $searchterm = trim($searchterm); $searchterm = explode('+', $searchterm); foreach ($searchterm as $value) { $sql = "SELECT COUNT(*), MATCH (article_title_".$lang.", article_text_".$lang.") AGINST (':queryString') AS score FROM ".$db_prefix."_base WHERE MATCH (article_title_".$lang.", article_text_".$lang.") AGAINST ('+:queryString')"; $sth = $dbh_pdo->prepare($sql); $sql_data = array('queryString' => $value); $sth->execute($sql_data); echo $sth->queryString; $row = $sth->fetchColumn(); if ($row < 1) { $sql = "SELECT * FROM article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString"; $sth = $dbh_pdo->prepare($sql); $sql_data = array('queryString' => $value); $sth->execute($sql_data); $row = $sth->fetchColumn(); } } //$row stays empty - no idea what is wrong if ($row > 1) { return true; } else { return false; } } 

Когда вы $sql_data массив $sql_data , вам нужно префикс имени параметра двоеточием:

 array('queryString' => $value); 

должно быть:

 array(':queryString' => $value); 

В вашем первом SELECT вас есть AGINST вместо AGAINST .

Кажется, что у вашего второго SELECT отсутствует имя таблицы после FROM и предложение WHERE . Параметры LIKE также неверно отформатированы. Это должно быть что-то вроде:

 sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE '%:queryString%' OR aricle_text_".$lang." LIKE '%:queryString%'"; 

Обновление 1 >>

Для обоих SELECT для каждого параметра требуются уникальные идентификаторы, а в значение должны быть помещены символы LIKE , а не оператор. Итак, ваше второе утверждение должно выглядеть так:

 sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString2"; 

Обратите внимание на queryString1 и queryString2 , без кавычек или % подстановочных знаков. Затем вам необходимо обновить массив:

 $sql_data = array(':queryString1' => "%$value%", ':queryString2' => "%$value%"); 

Подробные сведения об использовании нескольких параметров с одинаковым значением см. В разделе « Параметры » PDOStatement-> execute . Из-за этого я склонен использовать вопросительные знаки в качестве заполнителей вместо именных параметров. Я нахожу его более простым и опрятным, но это вопрос выбора. Например:

 sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE ? OR aricle_text_".$lang." LIKE ?"; $sql_data = array("%$value%", "%$value%"); 

<< Конец обновления 1

Я не уверен, для чего SELECT второй SELECT , так как я бы подумал, что если первый SELECT не нашел значение запроса, второй не нашел бы его. Но я многого не делал с полнотекстовыми поисками MySQL, поэтому я мог что-то упустить.

В любом случае, вам действительно нужно тщательно проверить SQL и любые ошибки. Вы можете получить информацию об ошибках, распечатав результаты PDOStatement->errorCode :

 $sth->execute($sql_data); $arr = $sth->errorInfo(); print_r($arr); 

Обновление 2 >>

Еще один момент, который стоит упомянуть: убедитесь, что при интерполяции переменных в ваш оператор SQL вы используете только доверенные данные. То есть не разрешайте использовать данные, предоставленные пользователем для имен таблиц или столбцов. Замечательно, что вы используете подготовленные операторы, но они защищают только параметры, а не ключевые слова SQL, имена таблиц и имена столбцов. Так:

 "SELECT * FROM ".$db_prefix."_base" 

… использует переменную как часть имени таблицы. Убедитесь, что эта переменная содержит доверенные данные. Если он исходит от ввода пользователя, сначала проверьте его на белый список.

<< Конец обновления 1

Вы должны прочитать функции полнотекстового поиска MySQL и функции сравнения строк . Вам нужно научиться строить базовые SQL-инструкции, иначе писать даже простую поисковую систему окажется чрезвычайно сложно.

На PHP-сайте также много примеров PDO. Вы можете начать с документации для PDOStatement-> execute , которая содержит некоторые примеры того, как использовать эту функцию.

Если у вас есть доступ к MySQL CLI или даже PHPMyAdmin, вы можете попробовать свой SQL без всяких путающих вещей PHP. Если вы собираетесь выполнять какую-либо работу по разработке базы данных как часть своего PHP-приложения, вы обнаружите, что сможете отлично протестировать SQL независимо от PHP.