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

    <sect2 id="zend.json.advanced.objects1">
        <title>JSON Objects</title>
        <para>
            When encoding PHP objects as JSON, all public properties of that object
            will be encoded in a JSON object.
        </para>
        <para>
            JSON does not allow object references, so care should be taken not to
            encode objects with recursive references. If you have issues with
            recursion, <methodname>Zend_Json::encode()</methodname> and
            <methodname>Zend_Json_Encoder::encode()</methodname> allow an optional second
            parameter to check for recursion; if an object is serialized twice, an
            exception will be thrown.
        </para>
        <para>
            Decoding JSON objects poses an additional difficulty, however, since
            Javascript objects correspond most closely to PHP's associative array.
            Some suggest that a class identifier should be passed, and an object
            instance of that class should be created and populated with the
            key/value pairs of the JSON object; others feel this could pose a
            substantial security risk.
        </para>
        <para>
            By default, <classname>Zend_Json</classname> will decode JSON objects as
            associative arrays. However, if you desire an object returned, you can
            specify this:
        </para>
        <programlisting language="php"><![CDATA[
// Decode JSON objects as PHP objects
$phpNative = Zend_Json::decode($encodedValue, Zend_Json::TYPE_OBJECT);
]]></programlisting>
        <para>
            Any objects thus decoded are returned as <code>StdClass</code> objects
            with properties corresponding to the key/value pairs in the JSON
            notation.
        </para>
        <para>
            The recommendation of Zend Framework is that the individual
            developer should decide how to decode JSON objects. If an object of a
            specified type should be created, it can be created in the developer
            code and populated with the values decoded using <classname>Zend_Json</classname>.
        </para>
    </sect2>

    <sect2 id="zend.json.advanced.objects2">
        <title>Encoding PHP objects</title>

        <para>
            If you are encoding PHP objects by default the encoding mechanism
            can only access public properties of these objects. When a method
            <methodname>toJson()</methodname> is implemented on an object to encode, <classname>Zend_Json</classname>
            calls this method and expects the object to return a JSON representation
            of its internal state.
        </para>
    </sect2>

    <sect2 id="zend.json.advanced.internal">
        <title>Internal Encoder/Decoder</title>

        <para>
            Zend_Json has two different modes depending if ext/json is enabled in
            your PHP installation or not. If ext/json is installed by default
            <methodname>json_encode()</methodname> and <methodname>json_decode()</methodname> functions
            are used for encoding and decoding JSON. If ext/json is not installed
            a Zend Framework implementation in PHP code is used for en-/decoding.
            This is considerably slower than using the php extension, but behaves
            exactly the same.
        </para>

        <para>
            Still sometimes you might want to use the internal encoder/decoder even
            if you have ext/json installed. You can achieve this by calling:
        </para>

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

    <sect2 id="zend.json.advanced.expr">
        <title>JSON Expressions</title>

        <para>
            Javascript makes heavy use of anonymnous function callbacks, which
            can be saved within JSON object variables. Still they only work if not
            returned inside double qoutes, which <classname>Zend_Json</classname> naturally does.
            With the Expression support for Zend_Json support you can encode JSON
            objects with valid javascript callbacks. This works for both <methodname>json_encode()</methodname>
            or the internal encoder.
        </para>

        <para>
            A javascript callback is represented using the <classname>Zend_Json_Expr</classname> object.
            It implements the value object pattern and is immutable. You can set the javascript
            expression as the first constructor argument. By default <classname>Zend_Json::encode</classname>
            does not encode javascript callbacks, you have to pass the option <code>'enableJsonExprFinder' = true</code>
            into the <code>encode</code> function. If enabled the expression support works for all nested expressions
            in large object structures. A usage example would look like:
        </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:
-->
