1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
<?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 <acronym>PHP</acronym> objects as <acronym>JSON</acronym>, all public
properties of that object will be encoded in a <acronym>JSON</acronym> object.
</para>
<para>
<acronym>JSON</acronym> 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 <acronym>JSON</acronym> objects poses an additional difficulty, however, since
Javascript objects correspond most closely to <acronym>PHP</acronym>'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 <acronym>JSON</acronym> object; others feel this could pose a
substantial security risk.
</para>
<para>
By default, <classname>Zend_Json</classname> will decode <acronym>JSON</acronym> 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 <classname>StdClass</classname> objects
with properties corresponding to the key/value pairs in the <acronym>JSON</acronym>
notation.
</para>
<para>
The recommendation of Zend Framework is that the individual
developer should decide how to decode <acronym>JSON</acronym> 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 <acronym>PHP</acronym> 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
<acronym>JSON</acronym> representation of its internal state.
</para>
</sect2>
<sect2 id="zend.json.advanced.internal">
<title>Internal Encoder/Decoder</title>
<para>
<classname>Zend_Json</classname> has two different modes depending if ext/json is
enabled in your <acronym>PHP</acronym> 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
<acronym>JSON</acronym>. If ext/json is not installed a Zend Framework implementation in
<acronym>PHP</acronym> code is used for en-/decoding. This is considerably slower than
using the <acronym>PHP</acronym> 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 <acronym>JSON</acronym> object variables. Still they only work if not
returned inside double qoutes, which <classname>Zend_Json</classname> naturally does.
With the Expression support for <classname>Zend_Json</classname> support you can encode
<acronym>JSON</acronym> 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 <property>enableJsonExprFinder</property> and set it to
<constant>TRUE</constant> into the <methodname>encode()</methodname> 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:
-->
|