<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.json.advanced">
    <title>Advanced Usage of Zend_Json</title>

    <sect2 id="zend.json.advanced.objects1">
        <title>Объекты JSON</title>

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

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

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

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

        <programlisting language="php"><![CDATA[
// Декодировать JSON объект как PHP объект
$phpNative = Zend_Json::decode($encodedValue, Zend_Json::TYPE_OBJECT);
]]></programlisting>

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

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

    <sect2 id="zend.json.advanced.objects2">
        <title>Кодирование объектов PHP</title>

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

    <sect2 id="zend.json.advanced.internal">
        <title>Внутренний кодировщик/декодировщик</title>

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

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

        <programlisting language="php"><![CDATA[
Zend_Json::$useBuiltinEncoderDecoder = true:
]]></programlisting>
    </sect2>

    <sect2 id="zend.json.advanced.expr">
        <title>Выражения JSON</title>

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

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

        <programlisting language="php"><![CDATA[
$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)
);
]]></programlisting>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->