Введение в JSON
Среди форматов обмена данными, AJAX программисты часто выделяют JSON (JavaScript Object Notation, "джейсн"), как альтернатива языку XML, а именно потому, что XML больше язык разметки, чем носитель данных. JSON в свою очередь, легкий, человеко-читабельный, текстовый формат для хранения и передачи простых структурированных данных, а так же более комплексных объектов (массивов). В этом уроке мы рассмотрим простой пример формирования данных в JSON средствами PHP, а так же их получение и представление, с помощью JavaScript. Кто еще не понял, это продолжение серии уроков "AJAX PHP поиск" (XML, Prototype).
JSON structure
Чем отличается представление данных в JSON от, допустим, XML. Простой пример:
-
{ "players" : [
-
{ "firstName" : "Ryan", "lastName" : "Campbell", "position" : "S" },
-
{ "firstName" : "Chris", "lastName" : "Campbell", "position" : "QB" },
-
{ "firstName" : "Kevin", "lastName" : "Hale", "position" : "DT" }
-
]}
Здесь у нас есть элемент players, который в свою очередь является массивом из трех "рядов", а каждый такой "ряд" это массив еще из трех элементов (firstName, lastName, position). Самое интересное то, что в языке JavaScript есть встроенная функция eval(), которая "парсит" (разбирает) такие строки.
Ну например, допустим у нас эти данные хранятся в переменной s (уже в JavaScript):
-
var obj = eval("(" + s + ")");
Мы получаем объект obj, который будет хранить все эти данные в очень удобной структуре:
-
alert(obj.players[0].firstName); // Ryan
-
alert(obj.players[1].lastName); // Campbell
-
alert(obj.players[2].position); // DT
Вот таким образом мы получаем доступ к JSON данным. Формирование таких данных мало чем отличается. Ну например на языке PHP:
На входе методу encode() подается любой массив, и метод возвращает закодированный в JSON такой же массив, готовый для передачи куда-либо.
Например..
Вспомним уроки создания AJAX поиска методами XML и Prototype. Попробуем еще разок продублировать этот пример, только уже с использованием JSON для представления данных.
Посмотреть в действии можно здесь:
http://logicerror.pp.ru/upload/ajax_search_json/
Начинаем:
- база данных MySQL
- html файл для вывода информации (index.html)
- AJAX скрипт (script.js)
- PHP двигатель (search.php)
В php5 уже встроены функции для работы с JSON данными. Для php4 качаем PEAR библиотеку json.php отсюда:
http://pear.php.net/pepr/pepr-proposal-show.php?id=198
База данных и HTML представление страницы у нас не изменилось совсем (ну кроме заголовка в HTML), так что у кого до сих пор нет, копируем отсюда:
http://www.ajaxrussia.com/archives/ajax-php-search-xml
AJAX
-
function getXmlHttp() {
-
var xmlhttp;
-
try {
-
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
-
} catch (e) {
-
try {
-
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
-
} catch (E) {
-
xmlhttp = false;
-
}
-
}
-
-
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
-
xmlhttp = new XMLHttpRequest();
-
}
-
return xmlhttp;
-
}
-
-
function search() {
-
var sSearch = document.getElementById("search_input").value;
-
-
if (sSearch.length <3)
-
{
-
alert("Запрос должен быть не короче 3-х символов.");
-
return false;
-
}
-
-
var xmlHttp;
-
xmlHttp = getXmlHttp();
-
-
var obj = document.getElementById("search_results");
-
obj.innerHTML = "";
-
var loading = document.getElementById("searching");
-
loading.style.display = "block";
-
-
xmlHttp.onreadystatechange = function() {
-
if (xmlHttp.readyState == 4)
-
{
-
loading.style.display = "none";
-
var json = eval( "(" + xmlHttp.responseText + ")" );
-
for (var i = 0; i <json.entry.length; i++)
-
{
-
var new_el = document.createElement("div");
-
new_el.innerHTML = "<h1>" + json.entry[i].title + "</h1>" + json.entry[i].content;
-
new_el.className = "result";
-
-
obj.appendChild(new_el);
-
}
-
}
-
}
-
-
xmlHttp.open('GET', 'search.php?search='+sSearch+'&rand='+Math.random(), true);
-
xmlHttp.send(null);
-
}
В script.js у нас произошли некоторые изменения в районе обработки и представления данных. Рассмотрим по порядку:
-
var json = eval( "(" + xmlHttp.responseText + ")" );
В переменную json, мы помещаем объект полученный функцией eval, которая целиком разбирает текст полученный с запрашиваемой страницы - xmlHttp.responseText (JSON ведь именно в текстовом формате данные хранит, помните?). Таким образом, переменная json у нас теперь полноценный объект с данными результата поиска.
-
for (var i = 0; i <json.entry.length; i++)
-
{
-
var new_el = document.createElement("div");
-
new_el.innerHTML = "<h1>" + json.entry[i].title + "</h1>" + json.entry[i].content;
-
new_el.className = "result";
-
-
obj.appendChild(new_el);
-
}
Здесь, узнав сколько всего записей у нас получено (json.entry.length, где entry у нас массив - поймете когда дойдем до части php), мы в цикле обрабатываем все элементы этих записей. То есть, как и в первом самом уроке, создаем новый элемент div, помещаем в него (.innerHTML) один сформированный результат поиска, присваиваем класс result, ну и наконец приклеиваем к объекту obj (поле для результатов поиска).
Теперь рассмотрим, как мы сформировали JSON данные.
PHP & JSON
-
<?php
-
-
require("json.php");
-
-
-
-
-
$sql="SELECT * FROM `articles` WHERE `title` LIKE '%$sString%' OR `content` LIKE '%$sString%' ORDER BY `id` DESC LIMIT 10";
-
-
{
-
$i = 0;
-
{
-
$entry["entry"][$i]["content"] = $content;
-
$i++;
-
}
-
}
-
else
-
{
-
$entry["entry"][0]["title"] = "";
-
$entry["entry"][0]["content"] = "Ничего не найдено";
-
}
-
-
$json = new Services_JSON();
-
?>
Подключение к базе данных и составление запроса поиска, думаю хватит уже обсуждать. Перейдем сразу к делу:
-
require("json.php");
Мы работаем на php4, так что обязательно подключаем PEAR библиотеку JSON (в которой и описан класс Services_JSON и методы encode/decode.
Согласно RFC 4627 JSON данные должны иметь MIME тип application/json, учтите это.
Создаем простой пустой массив $entry. Сюда мы будем записывать наши данные, а потом кодировать в формат JSON.
-
$i = 0;
-
{
-
-
$entry["entry"][$i]["content"] = $content;
-
$i++;
-
}
Здесь переменная $i будет служить в качестве счетчика, далее обрабатываем поля title и content из базы данных (как и раньше), и в своеобразной форме записываем в массив $entry. Расскажу о структуре массива. Первый элемент у нас всегда будет "entry" - мы так к нему обращаемся в javascript - json.entry. Второй элемент - порядковый номер результата (счетчик наш), так же используется в js - json.entry[i]. Ну и последние элементы - поля title и content. И таким же образом к ним обращается js - json.entry[i].title и json.entry[i].content.
-
$entry["entry"][0]["title"] = "";
-
$entry["entry"][0]["content"] = "Ничего не найдено";
В случае если поисковой запрос не дал результатов, мы в массив $entry помещаем всего одну запись - нчиего не найдено.
-
$json = new Services_JSON();
Здесь все просто. Создаем новый объект из класса Services_JSON(), и вызываем функцию encode(), передав наш массив $entry в качестве параметра. Ну и естественно выводим это все.
Заключение
Ну вот, собственно, и все.
По сравнению с XML, JSON более прост и удобен в использовании (особенно тем, кто хорошо ориентируется в массивах), но есть несколько нюансов по безопасности - обязательно проверяйте JSON данные на код javascript перед тем, как использовать его в eval(), т.к. эта функция исполняет javascript код.
Ну а с Prototype можно и не сравнивать, особенно если использовать их в паре - Prototype+JSON. Prototype для удобной работы с AJAX запросами, а JSON для удобного представления данных.
Полезные ссылки
del.icio.us Забобрить!5 Comments so far
Leave a reply
Я не уверен, но помоему PEAR’ная библиотека имела сложности с генерированием сложных вложенных объектов и массивов и приходилось всё переводить в массив.
Артём Курапов, ничего страшного, ведь это уже прошлое
почти…
Константин, а что скажете по поводу скорости обработки JSON по сравнению с XML? Судя по тому, что JSON — нативный формат JavaScript, он должен обрабатываться быстрее, чем парсинг XML.
Совершенно верно, JSON обрабатывается гораздо быстрее чем XML.
Спасибо автору, интересная и полезная статья.
Запостил у себя в блоге. Если найду время, напишу дополнение и свои навыки по этой теме.