Получение согласованного контекста полнотекстового поиска MySQL в PHP (и безопасность) - PullRequest
6 голосов
/ 04 марта 2011

Я выполняю полнотекстовый поиск по моим "страницам" в таблице MySQL. Я отображаю список страниц, которые соответствуют ключевому слову в их «заголовке» (обычный текст, VARCHAR, 255) или «контенте» (html, TEXT). Когда совпадение найдено в поле «содержимое», я хотел бы отобразить фрагмент, в котором совпадение было найдено. Я понятия не имею, как это сделать.

Можете ли вы поставить меня в правильном направлении?

$query = '  SELECT 
                *, 
                MATCH(title, content) AGAINST("'.$keyword.'") AS score 
            FROM 
                page 
            WHERE 
                MATCH(title, content) AGAINST("'.$keyword.'")
            ORDER BY 
                score 
            DESC    ';
$result = mysql_query($query) or die (mysql_error());
if(mysql_num_rows($result) > 0) {   
    $output .= '<p>Your keyword matches the following pages:</p>';
    while($row = mysql_fetch_assoc($result)){

        $title      = htmlentities($row['title']);
        $content    = htmlentities(strip_tags($row['content']));
        $content    = limit_text($content, 250); // Cuts it down to 250 characters plus ...

        $output .= '<h2>'.$title.'</h2>';
        if(trim($content) != '') {
            $output .= '<p>'.$content.'</p>'; // I'd like to place a snippet here with the matched context
        }           
    }   
} else {
    $output .= '<p>Keyword not found...</p>';       
}

Кроме того, у меня есть вопрос относительно безопасности. Сейчас я проверяю $keyword тремя способами:

  • Не пусто?
  • Более 2 символов?
  • Не опасно? (см. ниже)

Я использую регулярное выражение, чтобы соответствовать следующему, чтобы увидеть, опасен ли ввод пользователя

<script|&lt;script|&gt;script|document.|alert|bcc:|cc:|x-mailer:|to:|recipient|truncate|drop table

Это может быть немного нелепо и легко обойти, но это как минимум минимальная форма защиты от XSS-эксплойтов. Каков рекомендуемый способ обезопасить ключевое слово, предназначенное для поиска? PHPIDS перебор?

Ответы [ 3 ]

6 голосов
/ 04 марта 2011

Это должно помочь вам начать работу с частью "context" ...

// return the part of the content where the keyword was matched
function get_surrounding_text($keyword, $content, $padding)
{
    $position = strpos($content, $keyword);
    // starting at (where keyword was found - padding), retrieve
    // (padding + keyword length + padding) characters from the content
    $snippet = substr($content, $position - $padding, (strlen($keyword) + $padding * 2));
    return '...' . $snippet . '...';
}

$content = 'this is a really long string of characters with a magic word buried somewhere in it';
$keyword = 'magic';
echo get_surrounding_text($keyword, $content, 15); // echoes '... string with a magic word in it...'

Эта функция не учитывает случаи, когда границы заполнения выходят за пределы строки содержимого, например, когда ключевое слово найденов начале или в конце содержимого.Он также не учитывает несколько совпадений и т. Д. Но, надеюсь, он должен, по крайней мере, указать вам правильное направление.

2 голосов
/ 04 марта 2011

Вместо того, чтобы пытаться отфильтровать переменную $keywords самостоятельно, вы можете просто использовать подготовленный оператор и никогда не беспокоиться об отсутствии потенциального эксплойта:

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>
0 голосов
/ 04 марта 2011

Я бы, вероятно, получил бы ключевое слово $ для функции, чтобы сначала очистить его на вашем месте.и для записи вам лучше поместить все слова в ключевом слове $ в массив, чтобы при необходимости вы могли использовать логический поиск (например, поставить + перед каждым словом, чтобы получить эффект AND)

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