Безопасный и удобный поиск в mySQL. Безопасный и удобный поиск в mySQL Парень из далека

У Вас в браузере заблокирован JavaScript. Разрешите JavaScript для работы сайта!

Поиск по сайту с учетом морфологии русского языка на PHP + карта сайта

Создавая свой сайт Вы со временем задумаетесь о необходимости сделать на нем удобный универсальный поиск. Сходу есть простое решение: прикрутить поиск от поисковых систем, например: поиск от Яндекса или поиск от Гугла . Общий недостаток такого решения - в поисковом индексе будут только те страницы, которые поисковая система соблаговалила туда добавить. Иными словами часть Вашего сайта не будет "искаться".

Грустно, поищем другое решение. Да вот же оно: Яндекс.Сервер - это продукт для поиска по вашему сайту с учетом морфологии русского языка. Загрузка . В среде Unix Яндекс.Сервер работает как демон, а на платформе MS Windows - как сервис. Т.е. работать может только при root - доступе на сервер. При работе сайта на виртуальном хостинге не подходит. :-(Второй недостаток - никаких настроек. Только одна кнопка "Запустить/Остановить".

Начинаем "рыть" интернет. Ну как же так? У всех есть поиск на своем сайте. Как-то же люди его делают. Есть например, лобовое решение, давно описанное мной: контекстный поиск на сайте , который не учитывает склонение слов и не индексирует слова на страницах. Но чем дальше углубляешься в задачу тем больше понимаешь, что задача совсем нетривиальная.

Во-первых нужно просканировать весь сайт и выбрать с него все слова. Ну это я уже умею - генератор карты сайта давно с успехом справляется с этой задачей.

Во-вторых нужно получить исходную форму всех слов. Тут есть несколько вариантов, например можно использовать стример , который отрезает приставку, суффикс и окончание у слов. Или более сложную систему, использующую словари.

В третьих это все нужно загрузить в базу и проиндексировать, чтобы поиск занимал минимум времени.

Потратив две недели своего времени, перепробовав большое количество различных вариантов и алгоритмов я остановился на следующем:
1. Для сканирования я использую упрощенный парсер, который с помощью регулярного выражения вырезает все href со страницы:

// Получаем уникальные ссылки со страницы $html=file_get_contents($url); if(preg_match("|(.*?)|sei", $html, $arr)){ $body=trim($arr); if(preg_match_all("~~si",$body, $arr)) $links=array_unique($arr); }

Теперь нужно отделить внешние ссылки от внутренних и рекурсивно обратиться к парсеру с адресом внутренней ссылки. Вот тут и начинаются "грабли"... Внутренние ссылки могут быть указаны как внешние с http://домен/адрес, они могут быть относительно текущей страницы, они могут быть относительно тега base. Далее необходимо проверить не запрещена ли индексация этой страницы в robots.txt и не была ли эта страница уже отсканирована. Для проверки можно воспользоваться примером разбора robots.txt и примером поиска по SQL

$words=preg_split("/[^a-zA-Zа-яА-Я0-9]+/", $body, -1, PREG_SPLIT_NO_EMPTY);

убираем все короткие слова, преобразуем все слова к одному регистру и выделим основу(корень) слова. Для выделения корня слова лучше всего воспользоваться PHP - классом , который позволяет выделять корни слов с учетом морфологии русского, английского, украинского, эстонского или немецкого языков. Словари для каждого языка занимают 10-15 Мб. При этом не требуется устанавливать на сервер дополнительное программное обеспечение, все будет работать на самом обычном хостинге. Недостаток - низкая скрость выделения корня. Подключение библиотеки делается следующим образом:

$morphy=$path."phpmorphy/"; require_once($morphy."src/common.php"); $opts = array("storage" => PHPMORPHY_STORAGE_FILE, "predict_by_suffix" => true, "predict_by_db" => true, "graminfo_as_text" => true,); $morphy = new phpMorphy($morphy."dicts", "ru_RU", $opts);

У объекта phpMorphy три параметра:
первый - путь у папке словарей;
второй - кодовая страницы "ru_RU" - русский в utf-8, "rus"- русский в windows-1251;
третий - опции.

В опциях используется важный параметр storage, он может принимать одно из трех значений:

На виртуальном хостинге, скорее всего, придется использовать первый вариант, а на выделенном сервере для большей скорости лучше применять варианты с использованием памяти. Выберите вариант под свои задачи, если к модулю планируются частые обращения, то лучше, конечно, использовать вариант с разделяемой памятью.

Пример работы библиотеки phpmorphy есть .

3. Теперь нужно сделать таблицы базы данных, в которых мы будем хранить все результаты сканирования и разбора:

// список страниц сайта в виде ссылки, заголовка и анонса // (первых 300 символов страницы для вывода в результатах поиска). CREATE TABLE IF NOT EXISTS page (`id` int UNSIGNED NOT NULL PRIMARY KEY auto_increment, `url` varchar(255) not null default "" UNIQUE, `title` varchar(128) not null default "", `description` text not null default "") // все слова сайта. // word – то что осталось после стеммера (то что мы называли «корнем») // sound - результат функции soundex для данного слова. CREATE TABLE IF NOT EXISTS word (`id` INT UNSIGNED NOT NULL PRIMARY KEY auto_increment, `word` varchar(30) not null, `sound` char(4) not null default "A000") CREATE INDEX idx_word_word ON ".$search->word." (word(8)) CREATE INDEX idx_word_sound ON ".$search->word." (sound(4)) // Каждая строка – это слово «word», встретившеея на странице «page» «cnt»-раз CREATE TABLE IF NOT EXISTS index (`page` int UNSIGNED not null, `word` int UNSIGNED not null, `cnt` SMALLINT UNSIGNED NOT NULL, UNIQUE (page,word))

Теперь нужно сделать форму запроса поискового выражения. Простейшая форма поискового запроса выглядит так:

её код так:

Поиск:

Скачать скрипт поиска по сайту

На создание этого примера у меня ушло уж очень большое количество времени, поэтому хочется конвертировать его в деньги. Если Вы хотите повторить мой подвиг - удачи. Если Вы цените свое время, я с удовольствием обменяю время на деньги. Всего за 2900рублей (~46$) Вы получите полный открытый, подробно откоментированный скрипт поиска с генератором карты сайта.

Содержимое архива:
  • phpmorphy/ - библиотека для выдления корня слов
  • stemmer/ - выделение основы слова быстрым алгоритмом
  • config.php - настроки для работы с БД и общие функции, которые возможно вы уже используете и замените их на свои
  • index.php - поисковая форма + результаты поиска
  • install.php - создание таблиц БД MySQL для поиска
  • link_bar.php - постраничная навигация
  • search.php - класс для работы с поиском. Содержит методы:
    • sound_ex($string) - русский soundex для получения звучания слова
    • update($url, $scan=0) - рекурсивно сканировать все страницы сайта, выделить заголовок страницы, тело, описание.
    • ParsingWord($url, $words) - разбор слов и добавление их в поисковую базу
    • GetWords($words) - в переданном массиве заменяет все слова на их корни
    • url_short($url,$base="",$ext=0) - разбор ссылки, отделение внешних от внутренних
    • is_robots($url) - проверка присутствия ссылки в robots.txt
    • ReadUrl($site) - чтение страницы сайта с помощью Curl , обработка , - переадресации
  • sitemap.php - построение карты сайта sitemap.xml
  • spider_http.php - сканер сайта на основании чтения и разбора страниц
  • spider_sitemap.php - сканер сайта на основании разбора sitemap.xml

Инструкция по установке:

  • Распакуйте содержимое архива search.zip в папку search. Разрешите запись в неё из скриптов-установите права 777.
  • Отредактируете настроки использования БД в файле config.php Запустите install.php - будут созданы необходимые базы данных
  • Запустите "/search/spider_http.php" сканер наполняет таблицы базы:
    таблица всех страниц сайта, в неё попадают title, keywords и description.
    таблица слов, в неё попадают корни слов, найденных на страницах
    Возможно формирование базы на основании существующей карты сайта, для этого используйте "/search/spider_sitemap.php"
  • Размещаете поисковый запрос на страницах. Форма поискового запроса: Поиск:
  • Редактируете под себя формат вывода результатов на странице search.php
  • запускаете include_once "updater.php"; update($url);
    при добавлении, изменении или удалении каждой страницы
    $url - страница, которую нужно обновить.
    удобно вызывать после сохранения изменений страницы
    если страница возвращает 404 ошибку или она пустая - она будет удалена из базы.
  • запускаете "/search/sitemap.php" для создания карты сайта sitemap.xml
    не забудьте прописать путь к карте сайта в robots.txt: sitemap: /search/sitemap.xml
  • Возможности скрипта поиска по сайту
    • Сканирование всех страниц сайта с учетом запрета в robots.txt и
    • Разбор текста страниц с выделением слов, подсчет статистики слов
    • Выделение на странице title, keywords, description
    • Выделение корней слов с учетом морфологии русского языка и библиотек
    • Выделение основ слов быстрым алгоритмом(не рекомендуется, закоментировано в тексте скрипта)
    • Проверка русской орфографии при сканировании, основанная на отсутствии слова в словаре
    • Четыре режима сообщений: 0-работать молча, 1-выдавать только ошибки сайта, 2-выдавать ошибки и минимум информации, 3-подробное информирование при работе
    • Поиск по созвучию слов. Русский soundex.
    • Сортировка результатов поиска по релевантности. В первую очередь показываются страницы, на которых есть все поисковые слова в максимальном количестве.
    • Постраничный вывод найденных результатов
    • Скрипт подробно откомментирован на русском языке
    • Код скрипта реализован на PHP + MySQL, полностью открытый и не использует никаких дополнительных библиотек. Все необходимое идет в комплекте.
    • Генератор карты вашего сайта на основании базы, созданной сканером

      Что скрипт не может:

    • не учитываются , rel=nofollow
    • не убираются из поиска общие тексты, присутствующие на всех страницах

    Соглашение по использованию:

    • Вы можете использовать полученный код в любых своих разработках, вы не обязаны указывать ссылку на источник.
    • Вы НЕ имеете права перепродавать её, размещать в свободном или ограниченном доступе, а также публиковать в любом виде.
    • Все остальные права сохраняются за автором.
    • Вы можете обратиться к автору с вопросами, замечаниями, пожеланиями. Контакты .

    Будьте внимательны! За 2900 рублей (~46$) Вы можете выбрать один из двух вариантов скрипта, которые существенно отличаются друг от друга.
    Скрипт поиска для сайта в кодировке UTF-8 использует функции работы с двухбайтными символами mb_*, разбирает страницы регулярными выражениями сделанными для кодировки UTF-8 (unicod / Юникод), создает таблицы БД в utf-8.
    Скрипт поиска для сайта в кодировке Windows-1251 использует функции для работы только с однобайтными кодировками str*, разбирает страницы регулярными выражениями сделанными для однобайтных кодировок.

    Вы можете войти или зарегистрироваться ! Или без регистрации
    При нажатии кнопки загрузить, Вы подтверждаете согласие с условиями использования скрипта, описанными на этой странице.
    С Вашего баланса будет списана сумма в 2900 рублей (~46$) и начнется загрузка файла.

    Лучший способ удержать пользователя на сайте, это позволить ему найти, то что он ищет. Если вы делаете для этого удобную систему, то уровень предпочтения вашего сайта будет расти и пользователь обязательно вернётся для того, чтобы найти то, что его интересует.

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

    Я создам 2 файла: search.php, который будет содержать HTML и JavaScript. Второй файл, do_search.php будет содержать PHP код. Приступим к созданию первого файла:

    PHP, jQuery search demo $(function() { $(".search_button").click(function() { // получаем то, что написал пользователь var searchString = $("#search_box").val(); // формируем строку запроса var data = "search="+ searchString; // если searchString не пустая if(searchString) { // делаем ajax запрос $.ajax({ type: "POST", url: "do_search.php", data: data, beforeSend: function(html) { // запустится до вызова запроса $("#results").html(""); $("#searchresults").show(); $(".word").html(searchString); }, success: function(html){ // запустится после получения результатов $("#results").show(); $("#results").append(html); } }); } return false; }); }); Попробуйте ввести слово ajax
    Результаты для

    В этом файле мы создали обычную HTML форму, которая посылает POST запрос в бэк энд - файлу do_search.php.

    PHP код содержит комментарии, по которым вы с лёгкостью сможете понять работу скрипта. Если в базе данных нашлись совпадения, вы показываете их вашему пользователю, выделяя жирным те слова, которые искал пользователь.

    Придадим всему этому немного CSS:

    Body{ font-family:Arial, Helvetica, sans-serif; } *{ margin:0;padding:0; } #container { margin: 0 auto; width: 600px; } a { color:#DF3D82; text-decoration:none } a:hover { color:#DF3D82; text-decoration:underline; } ul.update { list-style:none;font-size:1.1em; margin-top:10px } ul.update li{ height:30px; border-bottom:#dedede solid 1px; text-align:left;} ul.update li:first-child{ border-top:#dedede solid 1px; height:30px; text-align:left; } #flash { margin-top:20px; text-align:left; } #searchresults { text-align:left; margin-top:20px; display:none; font-family:Arial, Helvetica, sans-serif; font-size:16px; color:#000; } .word { font-weight:bold; color:#000000; } #search_box { padding:4px; border:solid 1px #666666; width:300px; height:30px; font-size:18px;-moz-border-radius: 6px;-webkit-border-radius: 6px; } .search_button { border:#000000 solid 1px; padding: 6px; color:#000; font-weight:bold; font-size:16px;-moz-border-radius: 6px;-webkit-border-radius: 6px; } .found { font-weight: bold; font-style: italic; color: #ff0000; } h2 { margin-right: 70px; }

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

    Краткая справка по реализации поиска: Обработка строки, вырезание служебных символов, составление запроса к базе, логика, постраничный вывод, релевантность.

    Часть 1: Общие ведомости

    Обработка строки

    Первым делом надо порезать ручками строку.

    $search = substr($search, 0, 64);

    64 символа пользователю будет достаточно для поиска. Теперь каленым железом выжжем все "ненормальные" символы.

    $search = preg_replace("/[^\w\x7F-\xFF\s]/", " ", $search);

    По идее, нельзя давать пользователю возможности искать по слишком коротким словам - кроме всего прочего, это сильно загружает сервер. Итак, разрешим искать только по словам, которые длиннее двух букв (если ограничение больше, надо заменить "{1,2}" на "{1, кол-во символов}").

    $good = trim(preg_replace("/\s(\S{1,2})\s/", " ", ereg_replace(" +", " "," $search ")));

    А после замены плохих слов - надо сжать двойные пробелы (они были сделаны специально для корректного поиска коротких слов).

    $good = ereg_eplace(" +", " ", $good);

    Допустим, мы хотим предоставить пользователю возможность выбирать логику поиска - искать все слова или только одно из нескольких. Если вы хотите сделать как в Яндексе - два амперсанта означают "И" (слово1&&слово2&&слово3) или как-то еще, то я не советчик. Шаманство со строками на небольшом сайте imho не оправдывает затраченного времени. Поэтому форму для поиска рисуем так:

    искать любое из слов искать все слова

    А в поисковом скрипте лишний раз проверяем, что пользователь ввел:

    If (($logic!="AND") && ($logic!="OR"))
    $logic = "OR";

    Как будет использоваться логика - ниже.

    Статистика поиска

    Неплохо будет сразу информировать пользователя, сколько он нашел строк таблицы. Для этого делается дополнительный запрос в базу:

    $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%"")); else $stat="$v: короткое"; }; $word_stats = "Статистика слов: ". implode("", $stat). "
    "; unset($stat);

    Постраничный вывод результатов

    Ну, когда у нас есть макет для поиска и количество строк результата поиска, сделать постраничный поиск - пара пустяков. Проверяем переменную $page (не меньше 0, не больше $results_amount/$rows_in_page).В запрос, который подсчитывает количество строк (смотри выше), пишем нужные нам поля и поля для сортировки. А потом дописываем

    If ($page==0) $request .= "LIMIT $rows_in_page"; else $request .= "LIMIT ". $page*$rows_in_page. ",". $rows_in_page;

    (синтаксис: LIMIT либо LIMIT , )

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

    If ($page>0) print ("предыдущая страница"); if ($page0 ORDER BY relev DESC

    хотя можно:

    SELECT *, MATCH field AGAINST ("$searchwords") as relev FROM table WHERE MATCH field AGAINST ("$searchwords")>0 ORDER BY relev DESC

  • Скорость достаточно высокая - даже в некоторых случаях быстрее like поиска
  • Все вышесказанное работает начиная с версии MySQL 3.23.23
  • При создании индексов FULLTEXT по нескольким полям возможны 2 варианта:

    CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1, field2)) CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1), FULLTEXT (field2))

    В первом случае возможен запрос:

    SELECT *, MATCH field1, field2 AGAINST ("$searchwords") as relev FROM table ORDER BY relev DESC

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

    SELECT *, MATCH field1 AGAINST ("$searchwords")+MATCH field2 AGAINST ("$searchwords") as relev FROM table ORDER BY relev DESC

    Второй вариант несколько сложнее в запросах, однако, на мой взгляд лучше, т.к. увеличивается гибкость поиска - к каждому из полей можно задать, например, коэффициент значимости и при суммировании релевантностей полей умножать их на этот коэффициент. Поисковая фраза будет "больше" искаться в полях с большим коэффициентом. Например, если мы делаем поиск по проиндексированным страницам каталога ресурсов, то поле имени страницы обычно задают с большим коэффициентом, чем поля мета-тегов описаний или ключевых слов.

    Часть 3: Упражнения c релевантностью

    Сначала как добавить FULLTEXT-индекс:

    Mysql> alter table articlea add fulltext(ztext); ERROR 1073: BLOB column "ztext" can"t be used in key specification with the used table type mysql> alter table articlea type=myisam; Query OK, 36 rows affected (0.60 sec) Records: 36 Duplicates: 0 Warnings: 0 mysql> alter table articlea add fulltext(ztext); Query OK, 36 rows affected (10.00 sec) Records: 36 Duplicates: 0 Warnings: 0

    Текстовые индексы можно делать только в таблицах типа MyISAM. Тексты берутся из таблицы и скидываются в файл индекса, и растёт объём базы. По поводу запросов. Нельзя поле relev использовать в клаузе WHERE:

    SELECT *, MATCH field AGAINST ("$searchwords") as relev FROM table WHERE relev>0 ORDER BY relev DESC

    Хотя можно:

    SELECT *, MATCH field AGAINST ("$searchwords") as relev FROM table WHERE MATCH field AGAINST ("$searchwords")>0 ORDER BY relev DESC

    Вычисленное поле, конечно же, нельзя использовать в WHERE по всем правилам синтаксиса, но можно использовать в HAVING:

    SELECT *, MATCH field AGAINST ("$searchwords") as relev FROM table HAVING relev>0 ORDER BY relev DESC

    Поиск через MATCH, как писал Олег, делается только по слову целиком. ...Впрочем, по релевантности можно только сортировать, а выбирать по LIKE (это, конечно, скажется на производительности, даже не знаю, насколько).

    Убираем условие "relev>0", оставляем сортировку. Остальное, как и раньше - рубим полученную строку и превращаем в запрос с несколькими операторами LIKE:

    SELECT *,MATCH field AGAINST ("$searchwords") AS relev FROM table WHERE field LIKE "%$word1%" OR field LIKE "%$word2%" ORDER BY relev DESC, datefield DESC

    Часть 4: Продолежение начатого

    Продолжаю начатую в сентябре тему поиска с сортировкой по релевантности в базе MySQL.

    MySQL предлагает в последних версиях базы данных использовать для полнотекстового поиска индексацию FULLTEXT и конструкцию MATCH field AGAINST. Однако не на всех серверах стоит последняя версия MySQL, и не все хостинг-провайдеры хотят обновлять софт по соображениям надежности системы.

    В своё время я предполагал, что поиск с сортировкой по релевантности надо будет делать в несколько запросов, и, следовательно, лучше вовсе не браться за это. Мысли, что релевантность можно подсчитывать в самом запросе отдалённо меня посещали, но я боялся и представить такую конструкцию.

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

    SELECT title, date_format(material_date,"%e.%c.%y") AS date1, IF(text like "%word1 word2 word3%", 3*10, 0) + IF(text LIKE "%word1%", 9, 0) + IF(text LIKE "%word2%", 9, 0) + IF(text LIKE "%word3%", 9, 0) AS relevance FROM table WHERE text LIKE "%word1%" OR text LIKE "%word2%" OR text LIKE "%word3%" ORDER BY relevance DESC, material_date DESC

    Ужасно выглядит, но работает даже на старых версиях MySQL. Попробовал сравнить скорость работы с вот таким запросом:

    SELECT title, date_format(material_date,"%e.%c.%y") AS date1, MATCH text AGAINST("word1 word2 word3") AS relevance FROM table WHERE text LIKE "%word1%" OR text LIKE "%word2%" OR text LIKE "%word3%" ORDER BY relevance DESC, material_date DESC

    В среднем скорость универсального запроса в два раза меньше, чем использующего новые конструкции. Что вполне логично - чем больше универсальность, тем больше ресурсоёмкость.

    Попробуем построить такой запрос автоматически. Отрезаем длинную строку, а так же все неправильные символы и короткие слова. Рисуем запрос.

    $query = "SELECT title, date_format(material_date,"%e.%c.%y") AS date1, IF(text like "%". $good_words. "%", ". (substr_count($good_words, " ") + 1). "*10, 0) + IF(text LIKE "%". str_replace(" ", "%", 9, 0) + IF(text LIKE "%", $good_words). "%", 9, 0) AS relevance FROM table WHERE text LIKE "%". str_replace(" ", "%" OR text LIKE "%", $good_words). "%" ORDER BY relevance DESC, material_date DESC";

    Не очень-то сложно. Для надёжности и защиты от флуда можно ограничить количество слов в запросе.

    Некоторые дополнения к прежним публикациям

    Общее количество найденных строк в таблице. Для вывода результатов поиска, разумеется, надо пользоваться оператором LIMIT (чтобы не писать каждый раз формирование этого параметра, пользуйтесь готовыми функциями). Если никаких операций группировки в запросе не делается, лучше подсчитать количество строк сразу в запросе - COUNT(*), а не через функцию php mysql_num_rows(). Можете проверить на больших таблицах. Если производятся групповые операции, делаем запрос с COUNT(DISTINCT()), но без GROUP BY.

    Подсветка. Если в текстах не бывает html-тегов, жить проще

    $text = preg_replace("/word1|word2|word3/i", "\\0", $text);

    Если в тексте теги используются, то есть три варианта а) не делать подсветку б) поскольку теги пользователь не видит (разве что очень любопытный пользователь), то можно сделать поле индекса, в котором не будет тегов а символы [^\w\x7F-\xFF\s] будут заменены на пробелы (именно эти символы вырезаются из поисковой строки в самом начале, так что поиск по ним не производится). Поиск и подсветку в таком случае сделать именно по индексу. в) делать подсветку текста из обычного поля, предварительно вырезав теги функцией srip_tags() .

    Полная версия поискового кода, как всегда, в списке файлов.




    Есть еще вопросы или что-то непонятно - добро пожаловать на наш
    11.1K

    Одна из самых популярных и необходимых функций на любом сайте – это поиск, реализованный с помощью специальной формы. Этот функционал позволяет посетителям быстро находить на сайте интересующий их контент.

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

    Разрабатывать формы поиска при помощи PHP , а также познакомитесь с SQL (Structured Query Language ) – специальным языком для сбора, записи и модификации информации, содержащейся в базах данных. Перед тем как начать, рекомендуем вам скачать файлы проекта .

    Что вам понадобится

    • Инструмент для работы с базами данных MySQL .
    • Локальный или удаленный сервер с поддержкой PHP .
    • Текстовый редактор.
    Создаем базу данных

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

    Самым популярным инструментом для управления MySQL является PHP My Admin , Этого инструмента будет достаточно для нашего сегодняшнего руководства.

    Создание таблицы

    Наша таблица должна быть создана в следующем формате:

    Column Name Data Type Length Null or Not Null Primary key? Auto Increment
    ID INT 1 Not Null Yes Yes
    FirstName Varchar 50 Not Null No No
    LastName Varchar 50 Not Null No No
    Email Varchar 50 Not Null No No
    PhoneNumber Varchar 15 Not Null No No

    Таблица базы данных состоит из столбцов и строк, как в Excel . Первый столбец позволяет идентифицировать данные по имени. Далее идет колонка Data types (тип данных ), которая указывает нам на тип данных, содержащихся в колонке. В поле Length (Длина ) указывается максимальный объем памяти (хранилища ) для столбца таблицы. Мы используем переменные, которые дают больше гибкости. Другими словами, если длина ФИО меньше 50 символов, то будет занята лишь часть отведенного места.

    И среди данных персонала не может быть пустых значений (null, empty ). Первая строка выделена желтым цветом, потому что столбец ID – наш основной ключ. Основной ключ в базе данных гарантирует, что каждая запись будет уникальной. К этой колонке также применен автоинкремент, а это значит, что каждой записи в нашей базе данных будет присваиваться уникальный номер автоматически.

    Вносим представителей персонала в таблицу

    Как только разберетесь с таблицей, начните заполнять ее данными. 6 записей вполне достаточно, чтобы закрепить в уме процедуру. Ниже предлагаю вам собственный пример:

    Column ID FirstName LastName Email PhoneNumber
    2 Ryan Butler [email protected] 417-854-8547
    3 Brent Callahan [email protected] 417-854-6587
    Разработка формы

    Чтобы создать форму поиска по сайту через Google , откройте любой подходящий текстовый редактор. Я рекомендую воспользоваться бесплатным PSPad . Вы можете использовать любой текстовый редактор, где предусмотрена подсветка синтаксиса. Это в значительной степени облегчит процесс написания и отладки PHP-кода . Создавая страницу для формы поиска, не забудьте сохранить ее в формате .php , иначе PHP-код не будет обрабатываться должным образом. Как только сохраните документ, скопируйте в него следующую разметку:

    Поиск контактов:

    Детальный поиск контактов

    Вы можете искать по имени или фамилии

    Если вы знакомы с языком HTML , то тут вам все должно быть понятно как минимум до открывающего тега form . Внутри этого тега находится важнейший элемент всего кода – атрибут action . В качестве действия нашей формы мы указали название нашего файла, а затем применили к нему строку запроса “go ”.

    Проверка на соответствие критерию

    Когда пользователь вводит имя или фамилию, а затем нажимает кнопку подтверждения, форма передает данные самой себе и добавляет в конце строку запроса “go ”. На данном этапе мы проверяем наличие строки запроса go . Если результат положительный, выводим результаты поиска.

    До вывода запрашиваемых результатов нам нужно перепроверить: (1) была ли подтверждена форма, (2) содержит ли строка запроса значение go, (3) был ли поисковой запрос введен в нижнем или верхнем регистре? Если ни одна из проверок не дает положительного результата (true ), то от нас не требуется выполнять какие-либо действия.

    Для начала добавим небольшой блок кода PHP поиск по сайту после закрывающего тега :

    Сначала мы открываем блок PHP-кода тегом ””.

    Любой PHP-код внутри этой пары тегов будет исполняться сервером. Затем мы проверяем, была ли подтверждена форма:

    Мы воспользуемся встроенной функцией isset , которая возвращает значение типа bool , и поместим в нее массив $_POST . Логическое выражение в программировании позволяет получить нам либо true , либо false .

    Следовательно, если функция возвращает значение true , то форма была подтверждена, и нам нужно продолжить выполнение кода дальше. Если же функция возвращает значение false , то мы выведем сообщение об ошибке. Сохраните весь набранный код в файле search_submit.php .

    Мы вкладываем еще одно условное логическое выражение внутрь основного, но только в этот раз мы используем массив $_GET вместе со значением “go ”. Сохраните изменения в файле search_go.php .

    Теперь нам нужно убедиться, что посетители могут вводить первую букву в строку запроса только в верхнем или только в нижнем регистре. Нам также нужно предусмотреть способ учета критериев поиска, введенных посетителем. Лучше всего проверять введенные посетителем данные с помощью регулярного выражения:

    Мы вкладываем еще одно условное логическое выражение внутрь наших двух. На этот раз мы используем регулярное выражение для проверки ввода. Мы используем встроенную функцию preg_match с двумя параметрами: регулярное выражение, и поле формы, к которому должна применяться проверка.

    В нашем случае, это будет поле «Имя » (name ). Чтобы извлечь параметры поиска, указанные посетителем, мы создаем переменную $name, и привязываем к ней значение POST с названием поля из формы, которое будет использоваться в SQL-запросе . Сейчас мы реализовали: (1) отправку данных формы, (2) строка запроса включает значение go и (3) посетитель ввел либо заглавную, либо строчную первую букву. И все эти проверки происходят еще до внесения изменений в базу данных. Сохраните все изменения.

    Результаты Connect, Select, Query и Return из таблицы базы данных

    Чтобы получить данные из таблицы, сначала в скрипте поиска по сайту нужно подключиться к серверу. Для этого мы используем следующий код:

    Мы создаем переменную $db , и привязываем ее к встроенной функции MySQL mysql_connect , которая принимает три параметра: сервер с базой данных (localhost , если вы работаете локально ), логин и пароль.

    После этого мы запускаем встроенную PHP-функцию die , которая останавливает дальнейшее выполнение кода, если нет соединения с базой данных. И выводим информацию об ошибке, запуская встроенную функцию MySQL mysql_error , которая вернет причину ошибки. Сохраните файл search_connectdb.php .

    Создаем переменную под названием mydb и привязываем ее ко встроенной MySQL-функции mysql_select_db , а затем указываем название базы данных, которую создали ранее. Далее мы опрашиваем таблицу базы данных при помощи SQL-запроса с переменной name, в которой содержатся параметры поиска, введенные посетителем:

    При опросе таблицы базы данных мы создаем переменную $sql , и привязываем ее к строке, содержащей SQL-запрос . Мы используем оператор SELECT для извлечения значений из столбцов id , а также имени и фамилии из таблицы contacts . Затем мы используем инструкцию WHERE вместе со значениями имени и фамилии, чтобы сузить поиск.

    Вместе с оператором LIKE мы используем знак процента (%) – спецсимвол, который возвращает 0 и более знаков, а также переменную name из строки поиска. В результате LIKE (в сочетании со спецсимволом ) находит любое соответствующее имя в таблице базы данных. Можно описать весь процесс следующим образом: «Мы выбираем имя и фамилию из таблицы contacts , которые соответствуют введенным посетителем ». Сохраните файл search_query.php .

    Мы создаем переменную $result , и присваиваем ей значение функции mysql_query () , внося ее в $query. Теперь наш запрос хранится в переменной result . Чтобы вывести результат в PHP , мы создаем цикл, а затем выводим данные в неупорядоченном списке:

    Сначала мы создаем цикл while , внутри него создаем переменную под названием row , и инициализируем ее возвращаемым значением функции mysql_fetch_array , которая принимает переменную result , в которой находится наш SQL-запрос . Внутри цикла while мы присваиваем каждому значению столбца значение переменной с идентичным названием. Затем мы выводим значения внутрь неупорядоченного списка.

    Здесь важно обратить внимание на два момента: (1) внутри цикла while не нужно присваивать значения переменным массива row , так как значения можно брать напрямую из массива row ; (2) тег anchor , который мы используем в названии нашего файла вместе с id и основным ключом. Причина этого заключается в том, что во многих поисковых элементах изначально ничего не отображается.

    Так как мы показываем только имя и фамилию, приписывая ID в конце нашего тега anchor , то мы можем использовать ID для дополнительного запроса, который позволит вывести дополнительную информацию о персонале. Сохраните файл и протестируйте форму PHP поиска по сайту (search_display.php ).

    Убираем табуляцию

    Результаты выводятся в виде неупорядоченного списка, но суть в том, что нам не нужна табуляция. Чтобы избавиться от нее, добавьте следующее CSS-правило в самое начало вашего файла в head :

    ul li{ list-style-type:none; }

    Поиск по буквам

    Для реализации поиска по буквам потребуется лишь несколько дополнительных строк кода. Добавим этот удобный функционал для посетителей. Таким образом, они смогут находить представителей персонала по буквам, которые содержатся в имени или фамилии.

    Добавьте следующую строку кода после закрывающего тега form :

    A | B | K

    • Сергей Савенков

      какой то “куцый” обзор… как будто спешили куда то