Тестовый дизайн новой версии сайта IGD.BY         RU   |   EN
Передача массивов c кириллицей из PHP в JavaScript через JSON. Заполнение компонента jQuery UI Autocomplete данными из БД (MySQL). Реализация поиска на сайте
Автор: Кристофер

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

Мы покажем одно из множества решений, которое не раз было успешно опробовано на практике.

Из внешнего инструментария нам понадобится библиотека интерфейсных элементов jQuery UI. Этот виджет, а, если говорить точнее, метод, может "прикрепляться" к любому элементу input типа text, и позволяет облегчить задачу автоматического ввода текста с выбором варианта из массива слов. Настраивается очень легко и быстро, по указанной выше ссылке можно найти все необходимые работающие примеры.

Для старта работы нам необходимо иметь массив слов, которые будут применяться для автоподбора при вводе. Этот массив мы будем получать из БД посредством PHP, затем его перекодируем в формат JSON и автоматически передадим в JavaScript.

Форма у нас будет самая простая:

<form method="post" action="/search.php">
<input type="text" id="search" name="search"/>
<input type="submit" value="Найти"/>
</form>

Также, в целях упрощения, мы указали, что запрос из формы будет обрабатываться файлом search.php, который находится в корне сайта.  

Теперь перейдем к написанию PHP-кода. Допустим, мы заполним наш массив названиями (поле name) из таблицы table1.

<?
//заполняем массив из таблицы table1
$data=array();
$sql = 'SELECT * FROM table1 GROUP BY name';
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
  die('Нет доступа к таблице: ' . mysql_error());
}
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
$data[]=$row['name'];
}
?>

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


Далее самое интересное для случаев, когда мы работаем с кириллицей. Если мы добавим к этому PHP-коду строку $data=json_encode($data), то получим массив, в котором буквы на кириллице заменятся на символьные обозначения "\u...". В PHP, начиная с версии 5.4, для исправления ситуации можно использовать добавленную константу, и делать соотвествующий вызов $data = json_encode($data, JSON_UNESCAPED_UNICODE). Это срабатывает в большинстве случаев, но мы покажем более старый, но тем не менее надежный и "проверенный временем" вариант, а именно, напишем дополнительную функцию.

<?
//функция обработки кириллицы
function json_encode_cyr($str) {
$arr_replace_utf = array('\u0410', '\u0430','\u0411','\u0431','\u0412','\u0432',
'\u0413','\u0433','\u0414','\u0434','\u0415','\u0435','\u0401','\u0451','\u0416',
'\u0436','\u0417','\u0437','\u0418','\u0438','\u0419','\u0439','\u041a','\u043a',
'\u041b','\u043b','\u041c','\u043c','\u041d','\u043d','\u041e','\u043e','\u041f',
'\u043f','\u0420','\u0440','\u0421','\u0441','\u0422','\u0442','\u0423','\u0443',
'\u0424','\u0444','\u0425','\u0445','\u0426','\u0446','\u0427','\u0447','\u0428',
'\u0448','\u0429','\u0449','\u042a','\u044a','\u042b','\u044b','\u042c','\u044c',
'\u042d','\u044d','\u042e','\u044e','\u042f','\u044f');
$arr_replace_cyr = array('А', 'а', 'Б', 'б', 'В', 'в', 'Г', 'г', 'Д', 'д', 'Е', 'е',
'Ё', 'ё', 'Ж','ж','З','з','И','и','Й','й','К','к','Л','л','М','м','Н','н','О','о',
'П','п','Р','р','С','с','Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч','ч','Ш','ш',
'Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э','э','Ю','ю','Я','я');
$str = json_encode($str);
$str = str_replace($arr_replace_utf,$arr_replace_cyr,$str);
$str = str_replace('\\','',$str);
$str = str_replace('"[','[',$str);
$str = str_replace(']"',']',$str);
return $str;
}
?>

Соответственно, последующие вызовы будут выглядеть таким образом:

<?
//конвертируем в json
$data=json_encode($data);
$data=json_encode_cyr($data);
?>

Весь PHP-код будет выглядеть таким образом:

<?
//заполняем массив из таблицы table1
$data=array();
$sql = 'SELECT * FROM table1 GROUP BY name';
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
  die('Нет доступа к таблице: ' . mysql_error());
}
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
$data[]=$row['name'];
}
//конвертируем в json
$data=json_encode($data);
$data=json_encode_cyr($data);
//функция обработки кириллицы
function json_encode_cyr($str) {
$arr_replace_utf = array('\u0410', '\u0430','\u0411','\u0431','\u0412','\u0432',
'\u0413','\u0433','\u0414','\u0434','\u0415','\u0435','\u0401','\u0451','\u0416',
'\u0436','\u0417','\u0437','\u0418','\u0438','\u0419','\u0439','\u041a','\u043a',
'\u041b','\u043b','\u041c','\u043c','\u041d','\u043d','\u041e','\u043e','\u041f',
'\u043f','\u0420','\u0440','\u0421','\u0441','\u0422','\u0442','\u0423','\u0443',
'\u0424','\u0444','\u0425','\u0445','\u0426','\u0446','\u0427','\u0447','\u0428',
'\u0448','\u0429','\u0449','\u042a','\u044a','\u042b','\u044b','\u042c','\u044c',
'\u042d','\u044d','\u042e','\u044e','\u042f','\u044f');
$arr_replace_cyr = array('А', 'а', 'Б', 'б', 'В', 'в', 'Г', 'г', 'Д', 'д', 'Е', 'е',
'Ё', 'ё', 'Ж','ж','З','з','И','и','Й','й','К','к','Л','л','М','м','Н','н','О','о',
'П','п','Р','р','С','с','Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч','ч','Ш','ш',
'Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э','э','Ю','ю','Я','я');
$str = json_encode($str);
$str = str_replace($arr_replace_utf,$arr_replace_cyr,$str);
$str = str_replace('\\','',$str);
$str = str_replace('"[','[',$str);
$str = str_replace(']"',']',$str);
return $str;
}
?>


Другими словами, нам нужно подготовить массив в JSON таким образом чтобы в JavaScript он воспринимался бы как "родной". Дело в том, что, по существу JSON (англ. JavaScript Object Notation) - это по сути и есть JavaScript-код. 

Теперь подключаем jQuery UI, активизируем виджет Autocomplete, передаем туда массив $data, производим необходимые настройки.

<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
  $(function() {
    var availableTags = <?=$data;?>;
    $( "#search" ).autocomplete({
      source: availableTags,
      minLength:2
    });
  });
</script>

Как в видите, всё очень просто, в параметре minLength указывается номер вводимого символа, начиная с которого начинает срабатывать автозаполнение.  

Полный код формы с автозаполнением тестового поля:

<form method="post" action="/search.php">
<input type="text" id="search" name="search"/>
<input type="submit" value="Найти"/>
</form>

<?
//заполняем массив из таблицы table1
$data=array();
$sql = 'SELECT * FROM table1 GROUP BY name';
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
  die('Нет доступа к таблице: ' . mysql_error());
}
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
$data[]=$row['name'];
}
//конвертируем в json
$data=json_encode($data);
$data=json_encode_cyr($data);
//функция обработки кириллицы
function json_encode_cyr($str) {
$arr_replace_utf = array('\u0410', '\u0430','\u0411','\u0431','\u0412','\u0432',
'\u0413','\u0433','\u0414','\u0434','\u0415','\u0435','\u0401','\u0451','\u0416',
'\u0436','\u0417','\u0437','\u0418','\u0438','\u0419','\u0439','\u041a','\u043a',
'\u041b','\u043b','\u041c','\u043c','\u041d','\u043d','\u041e','\u043e','\u041f',
'\u043f','\u0420','\u0440','\u0421','\u0441','\u0422','\u0442','\u0423','\u0443',
'\u0424','\u0444','\u0425','\u0445','\u0426','\u0446','\u0427','\u0447','\u0428',
'\u0448','\u0429','\u0449','\u042a','\u044a','\u042b','\u044b','\u042c','\u044c',
'\u042d','\u044d','\u042e','\u044e','\u042f','\u044f');
$arr_replace_cyr = array('А', 'а', 'Б', 'б', 'В', 'в', 'Г', 'г', 'Д', 'д', 'Е', 'е',
'Ё', 'ё', 'Ж','ж','З','з','И','и','Й','й','К','к','Л','л','М','м','Н','н','О','о',
'П','п','Р','р','С','с','Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч','ч','Ш','ш',
'Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э','э','Ю','ю','Я','я');
$str = json_encode($str);
$str = str_replace($arr_replace_utf,$arr_replace_cyr,$str);
$str = str_replace('\\','',$str);
$str = str_replace('"[','[',$str);
$str = str_replace(']"',']',$str);
return $str;
}
?>

<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
  $(function() {
    var availableTags = <?=$data;?>;
    $( "#search" ).autocomplete({
      source: availableTags,
      minLength:2
    });
  });
</script>

Далее нам нужно написать сценарий обработки поисковых запросов, а именно, файл search.php. Согласно коду выше, на входе он получает только один элемент массива $_POST, а именно, $_POST['search']. Покажем самый простой пример обработки.

<?
if(isset($_POST['search'])){
	
	$sql = "SELECT * FROM table1 WHERE LOCATE('".$_POST["stroka"]."', description)";
	$retval = mysql_query( $sql, $conn );
	if(! $retval ){
		die('Нет доступа к таблице разделов: ' . mysql_error());
		}
	while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
	{
		echo($row['name']);
	}
}
?>

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