JSON это простой формат для сериализации данных в javascript, т.е. представления пременных в виде строки. Аналогично в php например есть функция serialize(), а в Java - RMI, в .NET - COM (если я не ошибаюсь), ну а в обобщённом виде - XML.
Лёгкий вес
Когда php-программисты ещё не знали о лёгком весе JSON, то для переносимости формата использовали XML. Так делает например FCKeditor до сих пор при получении списка в ресурс-менеджере. Ещё как есть плохой вариант - передавать сразу готовый HTML код. Но размер лишних данных в таком случае растёт в линейной прогрессии с коэффициентом полезные данные/тэги HTML.
Генерация в PHP
На серверной части в php 4 по умолчанию json отключён, но его можно попробовать включить..
dl(json.so);
$strToSend=json_encode($objToEncode);
Ещё вариант - использовать объект Services_JSON из громоздкого PEAR.
require_once('json.php');
$json = new Services_JSON();
$strToSend=$json->encode($objToEncode);
Но как правило первый вариант не работает, а второй странно ведёт себя с кодированием utf8. Поэтому мне пришлось немного дописать функцию до варианта, правильно кодирующий new-line символы:
function array2json($arr) {
$parts = array();
$is_list = false;
if (!is_array($arr)) return;
if (count($arr)<1) return '{}';
//Find out if the given array is a numerical array
$keys = array_keys($arr);
$max_length = count($arr)-1;
if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {//See if the first key is 0 and last key is length - 1
$is_list = true;
for($i=0; $i if($i != $keys[$i]) { //A key fails at position check.
$is_list = false; //It is an associative array.
break;
}
}
}
foreach($arr as $key=>$value) {
if(is_array($value)) { //Custom handling for arrays
if($is_list) $parts[] = array2json($value); /* :RECURSION: */
else $parts[] = '"' . $key . '":' . array2json($value); /* :RECURSION: */
} else {
$str = '';
if(!$is_list) $str = '"' . $key . '":';
//Custom handling for multiple data types
if(is_numeric($value)) $str .= $value; //Numbers
elseif($value === false) $str .= 'false'; //The booleans
elseif($value === true) $str .= 'true';
else $str .= '"' . addslashes($value) . '"'; //All other things
// :TODO: Is there any more datatype we should be in the lookout for? (Object?)
$parts[] = $str;
}
}
$json = implode(',',$parts);
if($is_list) return '[' . $json . ']';//Return numerical JSON
return '{' . $json . '}';//Return associative JSON
}
Приготавливаемся принять в браузере
Для того что-бы IE понял правильно utf-8 кодировку, надо указать заголовки. Данные можно передавать как обычным текстом, так и заголовками (что-бы из браузера нельзя было напрямую это увидеть)
header('Content-Type: application/json; charset=utf-8');
header('X-JSON: '.$myJsonData);
В Javascript получаем текст и декодируем его в данные функцией eval. Также не забываем преобразовывать символы новой строки, если они встречаются в данных. Во многих javascript-библиотеках функции для работы с json, сериализацией форм и прочая уже есть.
//пример для prototype.js
json = eval(t.getResponseHeader('X-JSON'));
//Пример для jQuery
$.getJSON('/someJsonURL',function(json){
json.descr=json.descr.replace(/\n/g,"
");
json.descr=json.descr.replace(/\t/g,"t");
}
По теме - обязательно посмотрите JSON saga о том как стандарт вводился и jsonlint для валидации
Комментарии
Самый простой вариант это наверно делать explode по запятым, а потом по двоеточиям с убиранием фигурных скобок и кавычек. Не сталкивался увы.
http://ua2.php.net/manual/ru/function.json-decode.php
$json->encode($php_arr)
Из JSON в php
$json->decode($json_arr);
http://ua2.php.net/manual/ru/json.setup.php
Для версии на Windows может быть нужно подправить php.ini и включить json.so - так же, как вы включаете mysql, curl, gd
Но эмулировать его не стоит :)
а то мне сотрудник эту статью показал как объяснение, зачем он написал свой json_encode на 5.2.6 :)
* убрал кусок "//It is an associative array.", тем более там была ошибка из-за него json для array('a'=>'b', 'c'=>'d', 'e'=>array('o'=>'p')) выдавал неверный результат. Я там ошибку нашёл, (она исправляется === вместо == на 10-ой строке), но мне кажется, привильнее записывать ключи что ассоциативного массива.
* добавил замену служебных символов
проверил на своём проекте, вроде бы всё ok, а Services_JSON выкинул :-)
function json_encode($arr) { $parts = array(); if (!is_array($arr)) return; if (count($arr) === 0) return '{}'; $keys = array_keys($arr); foreach($keys as $key) { if (is_array($arr[$key])) { //Custom handling for arrays $parts[] = '"' . $key . '":' . json_encode($arr[$key]); /* :RECURSION: */ } else { $str = '"'.$key.'":'; //Custom handling for multiple data types if (is_numeric($arr[$key])) $str .= $arr[$key]; //Numbers elseif ($arr[$key] === false) $str .= 'false'; //The booleans elseif ($arr[$key] === true) $str .= 'true'; else $str .= '"'.strtr($arr[$key], array('\\'=>'\\\\', '/'=>'\/', '"'=>'\"', "\b"=>'\b', "\t"=>'\t', "\n"=>'\n', "\f"=>'\f', "\r"=>'\r') ).'"'; //All other things $parts[] = $str; } } return '{'.implode(',', $parts).'}'; //Return associative JSON }спасибо автору
Вот это поможет
//Custom handling for multiple data types if(is_numeric($value)) { if (is_double($value)) { $str .= '"' . $value . '"'; } else { $str .= $value; } }