Только для читателей Lifeexample возможно открыть интернет-магазин на Moguta.CMS со скидкой в 15%
Формат JSON
Здравствуй уважаемый читатель блога LifeExample, пришло время разобраться с вопросом: "Как из PHP отдать в формате JSON данные". Сегодня мы поговорим о формате JSON, рассмотрим принципы работы с ним и напишем несколько примеров передачи сложных структур из PHP в JavaScript. Формат JSON получил такую хорошую актуальность среди веб приложений не только потому, что является подмножеством языка JavaScript, но и в силу своей легкой передачи и обрабатываемости на других языках, таких как PHP, Python, Perl , и др.
С появлением формата JSON можно отстраниться от использования формата XML для передачи данных между сервером и клиентом. Но совсем забывать о XML тоже не стоит, так как в его использовании есть много плюсов.
Что такое JSON
JSON – это языконезависимый текстовый формат обмена данными. Обычно используется при обмене данными между браузером и сервером. Формат JSON (JavaScript Object Notation), представляет собой JavaScript объект и является простой текстовой строкой.
Чтобы проще было понять, что такое JSON, немного расскажу о том, как создать объект в JavaScript. Существует два способа создания одного и того же объекта. Для наглядности давайте создадим объект описывающий продукцию интернет магазина.
Первый способ
Определение объекта каталога для магазина в JavaScript может выглядеть таким образом:
1 2 3 4 5 6 7 | <script> var Item = new Object(); Item.Name = "Футболка"; Item.Description = "Цветная футболка разных размеров" Item.price = 1500; Item.Availability = false; </script> |
Второй способ
Создать тот же объект можно с помощью литеральной нотации:
1 2 3 4 5 6 | var Item ={ "Name":"Футболка", "Description":"Цветная футболка разных размеров", "price":"1500", "Availability": false } |
Внимание! Литеральная аннотация, по сути, и является форматом JSON.
Другими словами если на запрос браузера в ответе сервера мы передадим текст:
1 2 3 4 5 6 | { "Name":"Футболка", "Description":"Цветная футболка разных размеров", "price":"1500", "Availability": false } |
И этот текст будет обработан в JavaScript соответствующей функцией для работы с форматом JSON, то мы получим тот самый объект.
Функция JavaScript для работы с JSON
Чтобы преобразовать полученную строку из ответа сервера в реальный объект с полями и методами, текст нужно пропустить через специальную функцию eval().
Функция eval() предназначена для выполнения JavaScript кода переданного ей в виде текста.
1 2 3 4 | <script> code = "alert('Привет мир!')"; eval(code); </script> |
В результате выполнения этого скрипта мы увидим сообщение «Привет мир!»:
Вернемся к нашему формату JSON. Принятую строку sData передадим в eval(), и выведем в сообщении весь список полей объекта.
1 2 3 4 5 6 | <script> var sData='{ "Name":"Футболка","Description":"Цветная футболка разных размеров","price":"1500","Availability": false}'; var Item = eval("(" + sData + ")"); text = "Продукт:"+"\n-"+Item.Name+"\n-"+Item.Description+"\n-"+Item.price+"\n-"+Item.Availability+"\n"; alert(text); </script> |
В результате получим:
Обратите вниание на форму передачи текста в eval():
1 | eval("(" + sData + ")"); |
Для корректной интерпретации JSON объекта нужно обрамить текст круглыми скобками.
Либо присвоить литеральную нотацию объекту:
1 | var Item = eval("obj = " + sData); |
В этом случае, сначала создастcя объект obj , а замет объект Item с полями с методами объекта obj.
С помощью формата JSON с сервера можно передавать такие данные как:
- запись,
- структура,
- хэш-таблица,
- список,
- ассоциативный массив.
Все эти структуры данных, поддерживаются любым современным языком программирования, что является весомым аргументом при выборе способа передачи данных с помощью JSON формата.
В концепцию JSON заложены такие понятия как:
Объект — множество пар имя:значение, в фигурных скобках { }, разделяемых двоеточием.
Пример объекта:
1 2 3 4 5 | { "Продукция": "Майка", "Стоимость": 1500, "Описание": "Цветная майка разных размеров" } |
Массив —множество индексированных значений заключенных в квадратные скобки.
Пример массива:
1 2 3 4 5 6 7 | { "Описание": { "Размер":["S","M","L","XL"], "Цвет" :["Красный","Зеленый","Синий"] } } |
Значение — число, строка, булевы значения true, false, null.
Пример использования различных значений:
1 2 3 4 5 6 7 8 9 | { "Продукция": "Майка", "Стоимость": 1500, "Наличие на складе": false, "Описание": { "Размер":["S","M","L","XL"], "Цвет" :["Красный","Зеленый","Синий"] } } |
Вот еще пример интерпретации сложного JSON объекта с вложенными массивами:
1 2 3 4 5 6 7 8 9 10 11 12 | <script> var sData='{ "Продукция": "Майка", "Стоимость": 1500, "Наличие на складе": false, "Описание": {"Размер":["S","M","L","XL"],"Цвет" :["Красный","Зеленый","Синий"]}}'; var Item = eval("obj = " + sData); text = "Продукт:" +"\n-"+Item['Продукция'] +"\n-"+Item['Стоимость'] +"\n-"+Item['Наличие на складе'] +"\n-"+Item['Описание']['Размер'][1] +"\n-"+Item['Описание']['Цвет'][1] alert(text); </script> |
Результат:
Как видите мы вытащили из объекта информацию хранившуюся во вложенных массивах:
1 2 | Item['Описание']['Размер'][1] Item['Описание']['Цвет'][1] |
Думаю со стороной клиента все понятно: получаем строку, преобразовываем в объект и работаем с ней дальше.
Как же быть со стороной сервера, не вручную ведь нам формировать JSON объекты…
Функции PHP для работы с JSON
Хвала разработчикам PHP, всю сложную работу они сделали за нас. Нам не придется самостоятельно писать парсеры PHP объектов, массивов и других структур. Если мы хотим получить массив в JSON формате, нам нужно только использовать встроенные готовые php функции: json_encode() и json_decode().
К примеру, мы имеем php скрипт оперирующий все тем же объектом каталога для интернет магазина.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Product{ public $name; public $price; public $description; function Product(){ $this->name = "Футболка"; $this->price = 1500; $this->description= array( "size"=>array("S","M","L","XL"), "color"=>array("Красный","Зеленый","Синий") ); } } $Item = new Product(); echo "<br/>".$Item->name; echo "<br/>".$Item->price; echo "<br/>".$Item->description['size'][1]; echo "<br/>".$Item->description['color'][1]; |
Теперь представим, что мы хотим передать наш созданный объект в формате JSON, для дальнейшего использования на стороне клиента. Все, что потребуется сделать это всего лишь передать в json_encode() экземпляр класса.
1 | $send_json=json_encode($Item); |
В результате выполнения такой строчки кода в переменную $send_json будет записана такая информация:
1 | {"name":"\u0424\u0443\u0442\u0431\u043e\u043b\u043a\u0430","price":1500,"description":{"size":["S","M","L","XL"],"color":["\u041a\u0440\u0430\u0441\u043d\u044b\u0439","\u0417\u0435\u043b\u0435\u043d\u044b\u0439","\u0421\u0438\u043d\u0438\u0439"]}} |
Этот страшный на первый взгляд набор символов, является сериализованным видом нашего объекта $Item. Так как в полях объекта используются кирилические символы, то функция заменяет их на ASCII коды, увеличивая при этом объем передаваемой информации. ( Подробнее об особенностях кодировок можно проитать в статье: PHP Кодировка страницы)
В этой статье я не буду описывать принципы передачи данных из PHP скрипта в JavaScript, так как планирую отдельно опубликовать материал по использованию технологии AJAX. В связи с этим предлогаю вручную перенести полученный JSON объект в код рассмотренного ранее JavaScript скрипта.
1 2 3 4 5 6 7 8 9 10 | <script> var sData='{"name":"\u0424\u0443\u0442\u0431\u043e\u043b\u043a\u0430","price":1500,"description":{"size":["S","M","L","XL"],"color":["\u041a\u0440\u0430\u0441\u043d\u044b\u0439","\u0417\u0435\u043b\u0435\u043d\u044b\u0439","\u0421\u0438\u043d\u0438\u0439"]}}'; var Item = eval("obj = " + sData); text = "Продукт:" +"\n-"+Item['name'] +"\n-"+Item['description']['size'][0]; alert(text); </script> |
Как мы можем видеть, клон объекта из PHP доступен теперь в JavaScript:
Теперь попробуем десериализовать полученные данные обратно с помощью json_decode().
Допустим мы в PHP скрипте получаем строку в формате JSON содержащую информацию об объекте:
1 2 3 4 5 6 7 8 9 | <?php $json='{"name":"\u0424\u0443\u0442\u0431\u043e\u043b\u043a\u0430","price":1500,"description":{"size":["S","M","L","XL"],"color":["\u041a\u0440\u0430\u0441\u043d\u044b\u0439","\u0417\u0435\u043b\u0435\u043d\u044b\u0439","\u0421\u0438\u043d\u0438\u0439"]}}'; $Item = json_decode($json, true); echo "<br/>".$Item['name']; echo "<br/>".$Item['price']; echo "<br/>".$Item['description']['size'][1]; echo "<br/>".$Item['description']['color'][1]; ?> |
Используем json_decode( ) для десериализации полученных данных, и записываем все это в переменную $Item. Таким образом, мы получили полноценный экземпляр класса Product .
Обратите внимание в коде вторым параметров в функцию передано значение ture
1 | json_decode($json, true); |
Это сделанно для того, чтобы избежать ошибки:
1 | Cannot use object of type stdClass |
Дело в том, что у нас в примере используются вложенные массивы для поля ‘description’, а без параметра true , функция json_decode() интерпретирует такие поля как stdClass, в следствии чего , потом к ним невозможно обратиться.
И напоследок представлю твоему вниманию уважаемый читатель, функцию с помощью которой можно сохранить читаемый вид объекта с кириллическими символами.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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','\u042d','\u044b','\u042c','\u044c', '\u042d','\u044d','\u042e','\u044e','\u042f','\u044f'); $arr_replace_cyr = array('А', 'а', 'Б', 'б', 'В', 'в', 'Г', 'г', 'Д', 'д', 'Е', 'е', 'Ё', 'ё', 'Ж','ж','З','з','И','и','Й','й','К','к','Л','л','М','м','Н','н','О','о', 'П','п','Р','р','С','с','Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч','ч','Ш','ш', 'Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э','э','Ю','ю','Я','я'); $str1 = json_encode($str); $str2 = str_replace($arr_replace_utf,$arr_replace_cyr,$str1); return $str2; } |
Итак, в данной статье мы рассмотрели много аспектов работы с форматом json, и статья получилась насыщенной, если у тебя читатель будут вопросы или пожелания к дополнению статьи другими примерами, то я всегда рад выслушать твои предложения. Пишите свои замечания и вопросы в комментариях к статье, подписывайтесь на регулярные обновления статей.
Читайте также похожие статьи:
Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.
Комментарии
Марк, привет!
Спасибо за статью, очень доходчиво!
А мы будем отдельно рассматривать внедрение JSON в рамках проекта PHP MVC SHOP?
Алексей
Да Алексей, конечно будем. Просто я решил сделать статью с описанием базовых принципов JSON, чтобы не загромождать уроки по созданию интернет магазина, ненужными отступлениями от сути, а просто отправлять по ссылке в нужный момент.
Mark, спасибо за труд, очень понравилось!
У тебя небольшая ошибка вот в этом коде в строке 7
2
3
4
5
6
7
8
var Item = eval("obj = " + sData);
text = "Продукт:"
+"\n-"+Item['name']
+"\n-"+Item['price']['size'][0];
alert(text);
Вот этот код ты имел в виду:
2
3
4
5
6
7
8
9
var Item = eval("obj = " + sData);
text = "Продукт:"
+ "\n-" + Item['name']
+ "\n-" + Item['price']
+ "\n-" + Item['description']['size'][0];
alert(text);
Я сначала тупо копипастил, но в конце концов пришлось разобраться что к чему.
Еще раз спасибо.
С уважением, Алексей
Спасибо за замечание, поправил. Зато сами разобрались 😉
решил помочь и разослал пост в соц. закладки. надеюсь поднимется популярность.
про eval это круто. А ведь некоторые подумают что так и нужно делать
eval очень опасная штуковина. ей ведь все рано,что ты передать. она выполнить javascript код попытается. и что там она сделает в браузере зависит от неё и кода. гораздо лучше. превращать переданные данные в объект,а уже потом манипулировать данными:
obj=json.parse(string);
obj.id ;
Спасибо, полезная статья, жаль нет практических примеров.
Спасибо!