SQL полнотекстовый поиск с PHP и PDO - PullRequest
0 голосов
/ 28 июля 2011

Я пытаюсь написать простой полнотекстовый поиск с помощью 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;
    }
}

1 Ответ

2 голосов
/ 28 июля 2011

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

array('queryString' => $value);

должно быть:

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

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

у вас есть AGINST.

В вашем втором 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 </strong>

Я не уверен, для чего предназначен второй 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 </strong>

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...