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 132 133 134 135
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.json.advanced">
<title>Fortgeschrittene Verwendung von Zend_Json</title>
<sect2 id="zend.json.advanced.objects1">
<title>JSON Objekte</title>
<para>
Bei der Kodierung von <acronym>PHP</acronym> Objekten nach <acronym>JSON</acronym>
werden alle öffentlichen Eigenschaften dieses Objektes im <acronym>JSON</acronym> Objekt
kodiert.
</para>
<para>
<acronym>JSON</acronym> erlaubt keine Objektreferenzen, deshalb sollte dafür Sorge
getragen werden, dass keine Objekte mit rekursiver Referenz kodiert werden. Wenn man
Probleme mit Rekursion hat, erlauben <methodname>Zend_Json::encode()</methodname> und
<methodname>Zend_Json_Encoder::encode()</methodname> die Angabe eines optionalen,
zweiten Parameters, um auf Rekursion zu prüfen; wenn ein Objekt doppelt serialisiert
wird, wird eine Ausnahme geworfen.
</para>
<para>
Das Dekodieren von <acronym>JSON</acronym> Objekten stellt eine weitere Schwierigkeit
dar, allerdings entsprechen Javascript Objekte sehr einem assoziativen Array in
<acronym>PHP</acronym>. Einige schlagen vor, dass ein Klassenbezeichner übergeben werden
soll und eine Objektinstanz dieser Klasse erstellt und mit den Schlüssel/Wert Paaren des
<acronym>JSON</acronym> Objektes bestückt werden soll; andere denken, dies könnte ein
erhebliches Sicherheitsrisiko darstellen.
</para>
<para>
Standardmäßig wird <classname>Zend_Json</classname> die <acronym>JSON</acronym> Objekte
als assoziative Arrays dekodieren. Wenn du allerdings wünscht, dass ein Objekt zurück
gegeben wird, kannst du dies angeben:
</para>
<programlisting language="php"><![CDATA[
// Dekodiere JSON Objekte als PHP Objekte
$phpNative = Zend_Json::decode($encodedValue, Zend_Json::TYPE_OBJECT);
]]></programlisting>
<para>
Jedes dekodierte Objekte wird als <classname>StdClass</classname> Objekt mit
Eigenschaften entsprechend der Schlüssel/Wert Paare der <acronym>JSON</acronym> Notation
zuürckgegeben.
</para>
<para>
Die Empfehlung des Zend Framework ist, dass der einzelne Entwickler selber entscheiden
sollte, wie er <acronym>JSON</acronym> Objekte dekodiert. Wenn ein Objekt eines
bestimmten Typs erstellt werden soll, kann es im Code des Entwicklers erstellt werden
und mit den dekodierten Werten unter Verwendung von <classname>Zend_Json</classname>
bestückt werden.
</para>
</sect2>
<sect2 id="zend.json.advanced.objects2">
<title>Kodierung von PHP Objekten</title>
<para>
Wenn man <acronym>PHP</acronym> Objekte kodiert, kann der Kodierungsmechanismus
standardmäßig nur auf public Eigenschaften dieser Objekte zugreifen. Wenn eine Methode
<methodname>toJson()</methodname> an einem Objekte für die Kodierung implementiert ist,
ruft <classname>Zend_Json</classname> diese Methode auf und erwartet dass das Objekt
eine <acronym>JSON</acronym> Repräsentation seines internen Status zurückgibt.
</para>
</sect2>
<sect2 id="zend.json.advanced.internal">
<title>Interner Encoder/Decoder</title>
<para>
<classname>Zend_Json</classname> hat zwei unterschiedliche Modi abhängig davon ob
ext/json in der <acronym>PHP</acronym> Installation aktiviert ist oder nicht. Wenn
ext/json installiert ist, werden standardmäßig die Funktionen
<methodname>json_encode()</methodname> und <methodname>json_decode()</methodname> für
die Kodierung und Dekodierung von <acronym>JSON</acronym> verwendet. Wenn ext/json nicht
installiert ist wird eine Implentierung vom Zend Framework in <acronym>PHP</acronym>
Code für die De-/Kodierung verwendet. Das ist naturgemäß langsamer als die Verwendung
der <acronym>PHP</acronym> Erweiterung, verhält sich aber identisch.
</para>
<para>
Machmal will man trotzdem den internen De-/Kodierer verwenden, selbst wenn man ext/json
installiert hat. Man kann das durch folgenden Aufruf erzwingen:
</para>
<programlisting language="php"><![CDATA[
Zend_Json::$useBuiltinEncoderDecoder = true:
]]></programlisting>
</sect2>
<sect2 id="zend.json.advanced.expr">
<title>JSON Ausdrücke</title>
<para>
Javascript macht häufige Verwendung von anonymen Funktions-Callbacks, welche in
<acronym>JSON</acronym> Objektvariablen gespeichert werden können. Trotzdem
funktionieren Sie nur wenn Sie nicht in doppelten Anführungszeichen gesetzt werden, was
<classname>Zend_Json</classname> natürlich macht. Mit der Unterstützung von Ausdrücken
für <classname>Zend_Json</classname> können <acronym>JSON</acronym> Objekte mit gültigen
Javascript Callbacks kodiert werden. Das funktioniert sowohl für
<methodname>json_encode()</methodname> als auch den internen Kodierer.
</para>
<para>
Ein Javascript Callback wird repräsentiert indem das
<classname>Zend_Json_Expr</classname> Objekt verwendet wird. Es implementiert das
Wert-Objekt Pattern und ist nicht änderbar. Man kann den Javascript Ausdruck als erstes
Argument des Konstruktors setzen. Standardmäßig kodiert
<classname>Zend_Json::encode</classname> keine Javascript Callbacks, wenn man die Option
<property>enableJsonExprFinder</property> auf <constant>TRUE</constant> setzt und der
<methodname>encode()</methodname> Funktion übergibt. Aktiviert, unterstützt arbeiten
Ausdrücke für alle enthaltenen Ausdrücke in großen Objektstrukturen. Ein
Verwendungsbeispiel würde wie folgt aussehen:
</para>
<programlisting language="php"><![CDATA[
$data = array(
'onClick' => new Zend_Json_Expr('function() { '
. 'alert("Ich bin ein gültiger Javascript Callback '
. 'erstellt von Zend_Json"); }'),
'other' => 'no expression',
);
$jsonObjectWithExpression = Zend_Json::encode(
$data,
false,
array('enableJsonExprFinder' => true)
);
]]></programlisting>
</sect2>
</sect1>
|