# Advanced Usage of Zend_Json

## Объекты JSON

Когда объекты PHP кодируются в JSON, все публичные свойства этого объекта будут кодированы в объект JSON.

JSON не поддерживает ссылки на объекты, поэтому следите за тем, чтобы не закодировать объекты с рекурсивными ссылками. Если вы имеете дело с рекурсией, то в вызове методов `Zend_Json::encode()` и `Zend_Json_Encoder::encode()` можно установить второй необязательный параметр для проверки на рекурсию; если один и тот же объект подвергается сериализации дважды, то будет сгенерировано исключение.

Декодирование объектов JSON представляет собой дополнительную сложность, так как объекты Javascript скорее соответствуют ассоциативным массивам в PHP. Одни советуют передавать идентификатор класса, экземпляр этого класса должен быть создан и заполнен парами ключ/значение объекта JSON; другие считают, что это может представлять собой серьезную угрозу безопасности.

По умолчанию `Zend_Json` будет декодировать объекты JSON как ассоциативные массивы. Но если вы хотите получить объект, то можете указать это:

    // Декодировать JSON объект как PHP объект
    $phpNative = Zend_Json::decode($encodedValue, Zend_Json::TYPE_OBJECT);

Любые объекты, декодированные таким образом, возвращаются как объекты `StdClass` со свойствами, соответствующими парам ключ/значение в нотации JSON.

Рекомендацией Zend Framework является то, что разрабочик должен сам принимать решение, как декодировать объект JSON. Если должен быть создан объект определенного типа, он может быть создан в коде разработчика и заполнен значениями, декодированными с помощью `Zend_Json`.

## Кодирование объектов PHP

Если вы кодируете объекты PHP, по умолчанию еханизм кодирования может получить доступ только к публичным свойствам этих объектов. Когда метод `toJson()` реализован в кодируемом объекте, `Zend_Json` вызывает его и ожидает возврат JSON представления внутреннего состояния объекта.

## Внутренний кодировщик/декодировщик

`Zend_Json` имеет два разных режима, в зависимости от того, включен ext/json в вашей сборке PHP или нет. Если ext/json установлен, по умолчанию будут использованы функции `json_encode()` и `json_decode()` для кодирования и декодированияJSON. Если же ext/json не установлен, то используется имплементации Zend Framework'а на PHP-коде. Эта имплементация значительно медленнее, чем расширение PHP, но ведет себя точно так же.

Иногда вы можете захотеть использовать внутренний кодировщик/декодировщик, даже если ext/json установлен. Вы можете добиться этого следующим способом:

    Zend_Json::$useBuiltinEncoderDecoder = true:

## Выражения JSON

Javascript широко использует анонимные функции обратного вызова, которые могут быть сохранены внутри переменных объекта JSON. Но они работают только если не возвращены внутри двойных кавычек, которые, естественно, `Zend_Json` ставит. С поддержкой выражений(Expressions) для `Zend_Json` вы можете кодировать объектыJSON, содержащие функции обратного вызова в javascript. Это работает как для `json_encode()`, так и для внутреннего кодировщика.

Javascript функции обратного вызова представлены с использованием объекта `Zend_Json_Expr`. Он реализует паттерн Value Object и является не неизменяемым. Вы можете установить выражение javascript первым аргументом конструктора. По умолчанию `Zend_Json::encode` не кодирует javascript функции обратного вызова, вы должны передать опцию enableJsonExprFinder со значением `TRUE` в функцию `encode()`. Если включена, подержка выражений работает для всех вложенных выражений в большой объектной структуре. Пример использования выглядит так:

    $data = array(
        'onClick' => new Zend_Json_Expr('function() {'
                  . 'alert("I am a valid javascript callback '
                  . 'created by Zend_Json"); }'),
        'other' => 'no expression',
    );
    $jsonObjectWithExpression = Zend_Json::encode(
        $data,
        false,
        array('enableJsonExprFinder' => true)
    );