1 <?xml version="1.0" encoding="UTF-8"?>
3 <!-- EN-Revision: 21740 -->
4 <sect1 id="zend.json.advanced">
5 <title>Zend_Json の高度な使用法</title>
7 <sect2 id="zend.json.advanced.objects1">
8 <title>JSON オブジェクト</title>
10 <acronym>PHP</acronym> オブジェクトを <acronym>JSON</acronym> にエンコードすると、
11 オブジェクトの public プロパティがすべて <acronym>JSON</acronym>
15 <acronym>JSON</acronym> はオブジェクトへの参照を扱うことができません。
16 再帰的な参照を伴うオブジェクトをエンコードしないように気をつけましょう。
18 <methodname>Zend_Json::encode()</methodname> および
19 <methodname>Zend_Json_Encoder::encode()</methodname>
20 のオプションの二番目のパラメータで再帰をチェックできます。
21 オブジェクトが二度シリアライズされると、例外がスローされるようになります。
24 <acronym>JSON</acronym> オブジェクトのデコードは、さらに大変です。Javascript
25 のオブジェクトを <acronym>PHP</acronym> に対応させるなら、連想配列にするのが一番近いでしょう。
26 しかし、中には「クラスの ID を渡してそのインスタンスを作成し、
27 <acronym>JSON</acronym> オブジェクトの キー/値 をそのインスタンスに代入すべきだという人もいます。
28 また、そんなことをするとセキュリティ上問題があるという人もいるでしょう。
31 デフォルトでは、<classname>Zend_Json</classname> は <acronym>JSON</acronym>
32 オブジェクトを連想配列にデコードします。しかし、
33 もしオブジェクトとして受け取りたいのなら、そのように指定することもできます。
35 <programlisting language="php"><![CDATA[
36 // JSONオブジェクトをPHPオブジェクトにデコードします
37 $phpNative = Zend_Json::decode($encodedValue, Zend_Json::TYPE_OBJECT);
40 このようにしてデコードされたオブジェクトは <code>StdClass</code>
41 オブジェクトとなり、<acronym>JSON</acronym> の キー/値
45 Zend Framework の推奨する方法は、各開発者が <acronym>JSON</acronym>
46 オブジェクトのデコード方法を決めるべきだというものです。
47 もし特定の型のオブジェクトを返してほしいのなら、
48 お望みの型のオブジェクトを開発者自身が作成したうえで、
49 <classname>Zend_Json</classname> がデコードした値をそこに代入していけばいいのです。
53 <sect2 id="zend.json.advanced.objects2">
54 <title>PHP オブジェクトのエンコード</title>
57 <acronym>PHP</acronym> オブジェクトをエンコードする際に、
58 デフォルトでエンコードメカニズムがアクセスできるのはオブジェクトの
59 public プロパティのみです。エンコードするオブジェクトに
60 <methodname>toJson()</methodname> メソッドが実装されていれば、
61 <classname>Zend_Json</classname> はこのメソッドを実行します。
62 このメソッドは、オブジェクトの内部状態を <acronym>JSON</acronym> 表現で返すものと期待されています。
66 <sect2 id="zend.json.advanced.internal">
67 <title>内部エンコーダ/デコーダ</title>
70 <classname>Zend_Json</classname> には二通りのモードがあり、<acronym>PHP</acronym> 環境で ext/json
71 が有効になっているかどうかによってどちらを使うかが変わります。
72 ext/json がインストールされていれば、デフォルトで
73 <methodname>json_encode()</methodname> 関数および <methodname>json_decode()</methodname>
74 関数を使用して <acronym>JSON</acronym> のエンコード/デコードを行います。
75 ext/json がインストールされていない場合は、<acronym>PHP</acronym> コードによる
76 Zend Framework の実装を用いてエンコード/デコードを行います。
77 これは <acronym>PHP</acronym> 拡張モジュールを使う場合にくらべて相当遅くなりますが、
82 しかし、ext/json がインストール環境で敢えて内部エンコーダ/
83 デコーダを使いたくなる場合もあるかもしれません。
87 <programlisting language="php"><![CDATA[
88 Zend_Json::$useBuiltinEncoderDecoder = true:
92 <sect2 id="zend.json.advanced.expr">
96 Javascript では無名関数のコールバックを多用します。
97 そしてそれが <acronym>JSON</acronym> オブジェクト変数内に保存されます。
98 これが動作するのはダブルクォートの中で返されていない場合のみであり、
99 <classname>Zend_Json</classname> は当然そのようにします。
100 <classname>Zend_Json</classname> の式サポートを使用すれば、<acronym>JSON</acronym> オブジェクトを
101 javascript コールバックとして正しい形式でエンコードできます。
102 これは、<methodname>json_encode()</methodname> と内部エンコーダの両方で動作します。
106 javascript コールバックは <classname>Zend_Json_Expr</classname> オブジェクトで表されます。
107 これは value object パターンを実装しており、不変 (immutable) です。
108 javascript の式を、コンストラクタの最初の引数として指定できます。
109 デフォルトでは <classname>Zend_Json::encode</classname> は javascript
110 コールバックをエンコードしません。エンコードするには、
111 オプション <code>'enableJsonExprFinder' = true</code> を
112 <code>encode</code> 関数に渡さなければなりません。これを有効にすると、
113 大きなオブジェクト構造の中の入れ子状の式に対しても式サポートが有効となります。
117 <programlisting language="php"><![CDATA[
119 'onClick' => new Zend_Json_Expr('function() {'
120 . 'alert("I am a valid javascript callback '
121 . 'created by Zend_Json"); }'),
122 'other' => 'no expression',
124 $jsonObjectWithExpression = Zend_Json::encode(
127 array('enableJsonExprFinder' => true)