PHP и формат передачи данных JSON

JSON (JavaScript Object Notation) – формат для обмена данными в текстовом виде. Позволяющий передавать сложные структуры данных в сериализованном виде. Этот формат передачи данных стал настолько популярен, что уже в ядро PHP начиная с версии 5.2.0, были добавлены функции по обработке данных в этом формате. А это значит, что нет необходимости в подключении дополнительных расширений. Формат данных JSON хорошо понятен человеку. Кроме того данный тип обмена данными широко используется между различными API сервисами. А при корректной разработке алгоритмов для обмена информацией, можно получить очень высокий прирост скорости чем, к примеру, при работе с данными в формате XML.

Отправка данных

Отправить данные в формате JSON можно двумя способами: сформировать GET или POST запрос с закодированными данными расположенными в GET или POST переменной или же поместить данные в тело документа. На практике обычно используется второй вариант.

Для произведения отправки данных необходимы нижеперечисленные функции:

  • string json_encode (mixed value [, int options = 0 ])

    В качестве параметра value указываются данные которые требуется закодировать. Поддерживается любой тип кроме типа resource. Параметр options содержит битовую маску из возможных предоставленных значений (см. таблицу с предоставленными JSON константами).

  • resource stream_context_create ([array options [, array params ]])

    Данная функция предназначена для создания и возврата контекста потока с опциями указанными в параметре options. Необязательный параметр options должен иметь тип ассоциативного массива. Изначально, он пуст. Второй необязательный параметр params также должен являться ассоциативным массивом в формате $data[‘имя’] = значение.

  • string file_get_contents (string filename [, bool use_include_path [, resource context [, int offset [, int maxlen]]]])

    Использование этой функции позволяет получить содержимое файла в виде строки. Параметр filename это имя считываемого файла. В параметре use_include_path начиная с версии PHP 5 можно использовать константу FILE_USE_INCLUDE_PATH для поиска файла в include path. Параметр context представляет ресурс контекста, созданный с помощью функции stream_context_create(). В случае неудавшейся попытки открытия файла, будет возвращено значение false. Параметр offset содержит смещение с которого начнется чтение данных. В параметре maxlen указывается размер получаемых данных.

    Примечание: смещение не указывается при работе, с удаленными потоками.

Ниже приведен пример отправки данных в формате JSON:

// Данные для отправки
$request = array(
	'StartDate' => '2013-10-10',
	'EndDate' => '2013-10-10',
	'IDS' => array(1,2,3,4,5,6,7)
);

// Указание опций для контекста потока
$options = array (
	'http' => array (
		'method' => 'POST',
		'header' => "Content-Type: application/json; charset=utf-8\r\n",
		'content' => json_encode($request)
	)
);

// Создание контекста потока
$context = stream_context_create($options);
// Отправка данных и получение результата
echo file_get_contents('http://test.ru/json.php', 0, $context);

Здесь используется импровизированная структура данных, состоящая из начальной и конечной даты, а также массива номеров некоторых условных записей. Обратите внимание на то, что в заголовке запроса Content-Type указывается тип “application/json”.

Получение данных

Для того чтобы получить переданные данные вышеописанным способом требуется произвести чтение данных из потока ввода “php://input”.

Используемые функции для принятия данных:

  • mixed json_decode (string json [, bool assoc = false [, int depth = 512 [, int options = 0 ]]])

    Данная функция декодирует строку в формате JSON. В параметре json указывается строка для декодирования. Параметр assoc отвечает за то, будут ли возвращаемые данные преобразованы в ассоциативный массив. Если таковая необходимость имеется, то необходимо указать в качестве значения этого параметра true. Параметр depth указывает на глубину рекурсии. И последний четвертый параметр options содержит битовую маску опций для декодирования. На сегодняшний день поддерживается только JSON_BIGINT_AS_STRING (по умолчанию большие целые числа приводятся к числам с плавающей запятой (float))

  • resource fopen (string filename, string mode [, bool use_include_path [, resource context]] )

    Открывает файл и возвращает его дескриптор. Параметр filename это именованный ресурс, указывающий на файл. В параметре mode указывается тип доступа к файлу (см. таблицу со списком возможных режимов для fopen()). Далее идут два необязательных параметра это: use_include_path и context. При установке параметра use_include_path в значение true или 1 и при условии, что в качестве именованного ресурса задан относительный путь, будет осуществлен поиск открываемого файла в списке директорий используемом функциями include и require. На практике этот параметр практически не используется. Параметр context используется для указания контекста ресурса.

  • string stream_get_contents (resource handle [, int maxlen = -1 [, int offset = -1 ]])

    Эта функция позволяет получить содержимое потока в виде строки. Параметр handle является ресурсом потока. Параметр maxlen содержит максимальное количество байт для чтения. По умолчанию он установлен в -1, что указывает на получение всех данных. Параметр offset содержит смещение, с которого начнется чтение данных. По умолчанию он также установлен в -1, что означает, что чтение будет произведено с начальной позиции.

Ниже приведен пример получения данных в формате JSON на стороне сервера:

// Открываем на чтение поток ввода
$f = fopen('php://input', 'r');

// Получаем содержимое потока
$data = stream_get_contents($f);

if ($data) {
	// Код обработки
	
	print_r(json_decode($data));
}

Полученная структура данных:

stdClass Object
(
    [StartDate] => 2013-10-10
    [EndDate] => 2013-10-10
    [IDS] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
            [4] => 5
            [5] => 6
            [6] => 7
        )

)

Примечание: необходимо учитывать тот момент, что для работы с форматом JSON, данные должны быть в кодировке utf-8.

Предоставленные JSON константы для функции json_encode()

JSON_HEX_TAG (integer) Все < и > кодируются в \u003C и \u003E. Доступна начиная с PHP 5.3.0.
JSON_HEX_AMP (integer) Все & кодируются в \u0026. Доступна начиная с PHP 5.3.0.
JSON_HEX_APOS (integer) Все символы ‘ кодируются в \u0027. Доступна начиная с PHP 5.3.0.
JSON_HEX_QUOT (integer) Все символы " кодируются в \u0022. Доступна начиная с PHP 5.3.0.
JSON_FORCE_OBJECT (integer) Выдавать объект вместо массива при использовании неассоциативного массива. Это полезно, когда принимающая программа или код ожидают объект или же массив пуст. Доступна начиная с PHP 5.3.0.
JSON_NUMERIC_CHECK (integer) Кодирование строк, содержащих числа, как числа. Доступна начиная с PHP 5.3.3.
JSON_BIGINT_AS_STRING (integer) Кодирует большие целые числа в виде их строковых эквивалентов. Доступна начиная с PHP 5.4.0.
JSON_PRETTY_PRINT (integer) Использовать пробельные символы в возвращаемых данных для их форматирования. Доступна начиная с PHP 5.4.0.
JSON_UNESCAPED_SLASHES (integer) Не экранировать /. Доступна начиная с PHP 5.4.0.
JSON_UNESCAPED_UNICODE (integer) Не кодировать многобайтные символы Unicode (по умолчанию они кодируются как \uXXXX). Доступна начиная с PHP 5.4.0.

 

Список возможных режимов для fopen() используя mode

‘r’ Открывает файл только для чтения; помещает указатель в начало файла.
‘r+’ Открывает файл для чтения и записи; помещает указатель в начало файла.
‘w’ Открывает файл только для записи; помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует — пробует его создать.
‘w+’ Открывает файл для чтения и записи; помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует — пытается его создать.
‘a’ Открывает файл только для записи; помещает указатель в конец файла. Если файл не существует — пытается его создать.
‘a+’ Открывает файл для чтения и записи; помещает указатель в конец файла. Если файл не существует — пытается его создать.
‘x’ Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выдаст ошибку уровня E_WARNING. Если файл не существует, попытается его создать. Это эквивалентно указанию флагов O_EXCL|O_CREAT для внутреннего системного вызова open(2).
‘x+’ Создаёт и открывает для чтения и записи; иначе имеет то же поведение что и’x’.
‘c’ Открывает файл только для записи. Если файл не существует, то он создается. Если же файл существует, то он не обрезается (в отличии от ‘w’), и вызов к этой функции не вызывает ошибку (также как и в случае с ‘x’). Указатель на файл будет установлен на начало файла. Это может быть полезно при желании заблокировать файл (смотри flock()) перед изменением, так как использование ‘w’ может обрезать файл еще до того как была получена блокировка (если вы желаете обрезать файл, можно использовать функцию ftruncate() после запроса на блокировку).
‘c+’ Открывает файл для чтения и записи; иначе имеет то же поведение, что и ‘c’.