Только для читателей Lifeexample возможно открыть интернет-магазин на Moguta.CMS со скидкой в 15%

<<< Модули интернет магазина || Корзина для интернет магазина php >>>

Формат JSON

24.02.2012
Формат 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>

В результате выполнения этого скрипта мы увидим сообщение «Привет мир!»:

Результат работы eval()

Вернемся к нашему формату 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>

В результате получим:

Интерпритация JSON нотации

Обратите вниание на форму передачи текста в eval():

1
eval("(" + sData + ")");

Для корректной интерпретации JSON объекта нужно обрамить текст круглыми скобками.
Либо присвоить литеральную нотацию объекту:

1
var Item = eval("obj = " + sData);

В этом случае, сначала создастcя объект obj , а замет объект Item с полями с методами объекта obj.

С помощью формата JSON с сервера можно передавать такие данные как:

  1. запись,
  2. структура,
  3. хэш-таблица,
  4. список,
  5. ассоциативный массив.

Все эти структуры данных, поддерживаются любым современным языком программирования, что является весомым аргументом при выборе способа передачи данных с помощью 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>

Результат:

Объект из формата JSON

Как видите мы вытащили из объекта информацию хранившуюся во вложенных массивах:

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 форматирование работает

Теперь попробуем десериализовать полученные данные обратно с помощью 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 ленту блога.

Нравится

Комментарии

  • Alexey

    Марк, привет!
    Спасибо за статью, очень доходчиво!
    А мы будем отдельно рассматривать внедрение JSON в рамках проекта PHP MVC SHOP?
    Алексей

  • Mark

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

  • hisava

    Mark, спасибо за труд, очень понравилось!
    У тебя небольшая ошибка вот в этом коде в строке 7

    1
    2
    3
    4
    5
    6
    7
    8
    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['price']['size'][0];

    alert(text);

    Вот этот код ты имел в виду:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var sData='{"name":"\u0424\u0443\u0442\u0431\u043e\u043b\u043a\u0430","price":16500,"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['price']
    + "\n-" + Item['description']['size'][0];

    alert(text);

    Я сначала тупо копипастил, но в конце концов пришлось разобраться что к чему.

    Еще раз спасибо.

    С уважением, Алексей

  • Mark

    Спасибо за замечание, поправил. Зато сами разобрались 😉

  • Dokemond

    решил помочь и разослал пост в соц. закладки. надеюсь поднимется популярность.

  • andre

    про eval это круто. А ведь некоторые подумают что так и нужно делать

  • andrey

    eval очень опасная штуковина. ей ведь все рано,что ты передать. она выполнить javascript код попытается. и что там она сделает в браузере зависит от неё и кода. гораздо лучше. превращать переданные данные в объект,а уже потом манипулировать данными:
    obj=json.parse(string);
    obj.id ;

  • Valeriy

    Спасибо, полезная статья, жаль нет практических примеров.

  • Артем

    Спасибо!

  • Оставить комментарий

    Подписаться на комментарии к этой статье по RSS

    Яндекс.Метрика