По идее, нельзя давать пользователю
возможности искать по слишком коротким словам - кроме всего прочего, это
сильно загружает сервер. Итак, разрешим искать только по словам, которые
длиннее двух букв (если ограничение больше, надо заменить "{1,2}" на
"{1, кол-во символов}").
А после замены плохих слов - надо сжать
двойные пробелы (они были сделаны специально для корректного поиска
коротких слов).
$ good = ereg_eplace("[ ]+", " ", $ good);
Логика
Допустим, мы хотим
предоставить пользователю возможность выбирать логику поиска - искать
все слова или только одно из нескольких. Если вы хотите сделать как в
Яндексе [2] [1] - два амперсанта
означают "И" (слово1&&слово2&&слово3) или как-то еще, то я не советчик.
Шаманство со строками на небольшом сайте imho не оправдывает
затраченного времени. Поэтому форму для поиска рисуем так:
Начало формы
Конец формы
А в поисковом скрипте лишний раз проверяем, что пользователь ввел:
if ($ logic!="AND" && $
logic!="OR")
$ logic = "OR";
Как будет использоваться логика — ниже.
Релевантность
Наверное, в том же
Яндексе [2] [1] все видели ссылочку
"сортировать по релевантности". Это оно и есть. Сортировка результатов
по количеству совпадений слов.
Отчасти, кстати, такая сортировка снимает проблему обработки логики
поиска. Но с БД MySQL делать такую сортировку очень сложно. Надо сперва
выбрать, где есть все слова, потом записи, где разные слова (исключив
предыдущие). Если у вас постраничный вывод - то вообще дело труба!
Статистика поиска
Неплохо будет сразу информировать
пользователя, сколько он нашел строк таблицы. Для этого делается
дополнительный запрос в базу:
$ query = "SELECT id FROM table
WHERE field LIKE '%". str_replace(" ", "%' OR field LIKE '%", $ good).
"%'";
Для статистики по отдельным словам можно
сделать следующее:
$ word = explode(" ", $search);
while (list($ k, $ v) = each($ word)) {
if (strlen($ v)>2)
$ stat[]="$ v:". mysql_num_rows(mysql_query("SELECT id FROM table
WHERE field LIKE '%$ v%'"));
Ну, когда у нас есть макет для поиска и
количество строк результата поиска, сделать постраничный поиск - пара
пустяков. Проверяем переменную $ page (не меньше 0, не больше $
results_amount/$ rows_in_page).
В запрос, который подсчитывает количество строк (смотри выше), пишем
нужные нам поля и поля для сортировки. А потом дописываем
Пробелы (а они у нас между словами стоят
поодиночке, и нигде двойной пробел не встречается, к тому же с концов
строки мы их тоже вырезали) достаточно заменить на вертикальную черту -
разделитель вариантов в регулярных выражениях. "Плохие" слова мы не
подсвечиваем, потому что в базе их не ищем :).
После написания выпуска я кинулся, было,
писать и себе "подсветку". Не тут-то было! У меня в тексте встречаются
теги HTML, поэтому пришлось много подумать... Получилась вот такая вещь
(строка со словами для подсветки есть):
$ text = eregi_replace(">([^<]*)$
words", ">1<font color=#cc0000>2</font>3<", $ text);
Приходится смотреть, нет в теге ли это слово.
Однако тут встает проблема ресурсоемкости такой замены (мой K6-266 над
текстом в 5 килобайт думал целых семь секунд). Печально.
Итог
Применяя такие приемы, можно, во-первых, ограничить свободу действий
пользователя и не дать ему а) узнать программную структуру сайта б)
вызвать перегрузку сервера (например, отправив мегабайт текста,
состоящего из слов длиной в три буквы (фраза получилась двусмысленная,
но переписывать не буду :), чтобы скрипт 250 тысяч раз лазил в базу) в)
увидеть сообщение об ошибке в результате попадания в строку спецсимволов
языка запросов. Во-вторых, некоторое удобство для пользователя -
постраничный вывод и подсветка.
Опубликовал Kest
October 26 2008 12:47:09 ·
0 Комментариев ·
7348 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.