[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / ja / module_specs / Zend_Amf-Server.xml
blobef4e4f5bb0dcca4221ede53a9e135ad428fe0555
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <!-- EN-Revision: 21741 -->
4 <sect1 id="zend.amf.server">
5     <title>Zend_Amf_Server</title>
7     <para>
8         <classname>Zend_Amf_Server</classname> は <acronym>RPC</acronym> スタイルのサーバで、
9         Adobe Flash Player からの <acronym>AMF</acronym> プロトコルによるリクエストを処理します。
10         他の Zend Framework のサーバクラス群と同様に SoapServer <acronym>API</acronym> にしたがっており、
11         サーバを作成するための習得しやすいインターフェイスを提供します。
12     </para>
14     <example id="zend.amf.server.basic">
15         <title>基本的な AMF サーバ</title>
17         <para>
18             さまざまな public メソッドを持つクラス <classname>Foo</classname>
19             を作ったものとしましょう。<acronym>AMF</acronym> サーバを作成するためのコードは次のようになります。
20         </para>
22         <programlisting language="php"><![CDATA[
23 $server = new Zend_Amf_Server();
24 $server->setClass('Foo');
25 $response = $server->handle();
26 echo $response;
27 ]]></programlisting>
29         <para>
30             もうひとつの方法として、単純な関数をコールバックとしてアタッチすることもできます。
31         </para>
33         <programlisting language="php"><![CDATA[
34 $server = new Zend_Amf_Server();
35 $server->addFunction('myUberCoolFunction');
36 $response = $server->handle();
37 echo $response;
38 ]]></programlisting>
40         <para>
41             複数のクラスや関数を混ぜて使用することもできます。
42             その場合は、それぞれに名前空間を指定してメソッド名の衝突を回避させることをおすすめします。
43             名前空間を指定するには、<methodname>addFunction()</methodname> あるいは
44             <methodname>setClass()</methodname> の 2 番目の引数に文字列を指定します。
45         </para>
47         <programlisting language="php"><![CDATA[
48 $server = new Zend_Amf_Server();
49 $server->addFunction('myUberCoolFunction', 'my')
50        ->setClass('Foo', 'foo')
51        ->setClass('Bar', 'bar');
52 $response = $server->handle();
53 echo $response;
54 ]]></programlisting>
56         <para>
57         <classname>Zend Amf Server</classname> は、
58         指定したディレクトリパスから動的にサービスに読み込ませることもできます。
59         好きなだけのディレクトリをサーバに指定することが可能です。
60         サーバに後から追加したディレクトリから順に (<acronym>LIFO</acronym>: 後入れ先出し)
61         検索を行い、クラスにマッチするディレクトリを探します。
62         ディレクトリの追加は <methodname>addDirectory()</methodname> メソッドで行います。
63         </para>
65         <programlisting language="php"><![CDATA[
66 $server->addDirectory(dirname(__FILE__) .'/../services/');
67 $server->addDirectory(dirname(__FILE__) .'/../package/');
68 ]]></programlisting>
70         <para>
71         リモートサービスをコールする際には、アンダースコア ("_") およびドット
72         (".") をディレクトリ区切り文字として使用します。
73         アンダースコアを使用すると、<acronym>PEAR</acronym> や
74         Zend Framework のクラス命名規約に従った形式となります。
75         つまり、サービス com_Foo_Bar をコールした場合は、
76         インクルードされたパスのどこかにある
77         <filename>com/Foo/Bar.php</filename> を探します。ドット記法を使用してリモートサービスを
78         <filename>com.Foo.Bar</filename> のように指定すると、
79         インクルードされたパスの最後に <filename>com/Foo/Bar.php</filename>
80         を追加して <filename>Bar.php</filename> を自動的に読み込みます。
81         </para>
83         <para>
84             スクリプトに送られたすべての <acronym>AMF</acronym> リクエストがサーバで処理され、
85             その結果の <acronym>AMF</acronym> レスポンスが返されます。
86         </para>
87     </example>
89     <note>
90         <title>アタッチされるすべてのメソッドや関数には docblock が必要</title>
92         <para>
93             Zend Framework の他のサーバコンポーネント群と同様、クラスのメソッドには
94             <acronym>PHP</acronym> docblock 形式のドキュメントが必要です。
95             少なくとも必須引数と返り値についてのアノテーションが必要となります。
96             次の例をごらんください。
97         </para>
99         <programlisting language="php"><![CDATA[
100 // アタッチする関数
103  * @param  string $name
104  * @param  string $greeting
105  * @return string
106  */
107 function helloWorld($name, $greeting = 'Hello')
109     return $greeting . ', ' . $name;
111 ]]></programlisting>
113         <programlisting language="php"><![CDATA[
114 // アタッチするクラス
116 class World
118     /**
119      * @param  string $name
120      * @param  string $greeting
121      * @return string
122      */
123     public function hello($name, $greeting = 'Hello')
124     {
125         return $greeting . ', ' . $name;
126     }
128 ]]></programlisting>
130         <para>
131             その他のアノテーションを使用することもできますが、無視されます。
132         </para>
133     </note>
135     <sect2 id="zend.amf.server.flex">
136         <title>サーバへの Flex からの接続</title>
138         <para>
139             <classname>Zend_Amf_Server</classname> に Flex プロジェクトから接続するのはきわめて簡単です。
140             エンドポイントの <acronym>URI</acronym> を
141             <classname>Zend_Amf_Server</classname> スクリプトに指定するだけでよいのです。
142         </para>
144         <para>
145             たとえば、作成したサーバをアプリケーションルートに
146             <filename>server.php</filename> という名前で配置したとしましょう。<acronym>URI</acronym> は
147             <filename>http://example.com/server.php</filename> となります。
148             この場合は、services-config.xml ファイルを編集して、
149             チャンネルのエンドポイント URI 属性をこの値に変更します。
150         </para>
152         <para>
153             まだ <filename>service-config.xml</filename> ファイルを作っていない場合は、
154             まずナビゲータウィンドウでプロジェクトを開きます。
155             そしてプロジェクト名のところを右クリックして 'プロパティ' を選択します。
156             プロジェクトのプロパティダイアログで 'Flex ビルドパス' を選択し、
157             'ライブラリパス' タブで '<filename>rpc.swc</filename>'
158             ファイルがプロジェクトに追加されていることを確認したら、
159             OK を押してウィンドウを閉じます。
160         </para>
162         <para>
163             また、リモートオブジェクトのエンドポイントを探す際に <filename>service-config.xml</filename>
164             を使用することをコンパイラに指定する必要もあります。
165             ナビゲータのプロジェクトフォルダを右クリックしてプロパティを選択し、
166             もういちどプロジェクトのプロパティパネルを開きます。
167             そこで 'Flex コンパイラ' を選択して、
168             <command>-services "services-config.xml"</command> を追加します。
169             適用、そして OK を押してオプションを更新します。
170             これで結局何をやったのかというと、実行時の変数を
171             <filename>services-config.xml</filename> から読み込んで RemotingObject クラスで使うよう
172             Flex コンパイラに指示したということです。
173         </para>
175         <para>
176             それから、リモートメソッドへの接続の際に使用するサービス設定ファイルを
177             Flex に教えてやる必要があります。そこで、Flex プロジェクトの src フォルダに
178             '<filename>services-config.xml</filename>' ファイルを新たに作成します。
179             プロジェクトフォルダで右クリックして '新規作成' 'ファイル'
180             を選択すると新しいウィンドウが開きます。プロジェクトフォルダを選択し、
181             ファイル名を '<filename>services-config.xml</filename>' と指定して終了を押します。
182         </para>
184         <para>
185             Flex は新しい <filename>services-config.xml</filename> ファイルを作成し、それを開きます。
186             次の例のとおりに <filename>services-config.xml</filename> ファイルを作成してください。
187             エンドポイントの部分はあなたが使用するサーバに書き換えます。
188             そしてファイルを保存することを忘れないようにしましょう。
189         </para>
191         <programlisting language="xml"><![CDATA[
192 <?xml version="1.0" encoding="UTF-8"?>
193 <services-config>
194     <services>
195         <service id="zend-service"
196             class="flex.messaging.services.RemotingService"
197             messageTypes="flex.messaging.messages.RemotingMessage">
198             <destination id="zend">
199                 <channels>
200                     <channel ref="zend-endpoint"/>
201                 </channels>
202                 <properties>
203                     <source>*</source>
204                 </properties>
205             </destination>
206         </service>
207     </services>
208     <channels>
209         <channel-definition id="zend-endpoint"
210             class="mx.messaging.channels.AMFChannel">
211             <endpoint uri="http://example.com/server.php"
212                 class="flex.messaging.endpoints.AMFEndpoint"/>
213         </channel-definition>
214     </channels>
215 </services-config>
216 ]]></programlisting>
218         <para>
219             この例にはポイントがふたつあります。まず
220             <acronym>AMF</acronym> チャネルを作成し、そしてエンドポイントの <acronym>URL</acronym> を
221             <classname>Zend_Amf_Server</classname> に指定します。
222         </para>
224         <programlisting language="xml"><![CDATA[
225 <channel-definition id="zend-endpoint"
226     <endpoint uri="http://example.com/server.php"
227         class="flex.messaging.endpoints.AMFEndpoint"/>
228 </channel-definition>
229 ]]></programlisting>
231         <para>
232             このチャネルの ID として "zend-endpoint" を指定したことに注意しましょう。
233             この例では、このチャネルを指すサービスを作成して、その ID を指定しました。
234             この場合の ID は "zend" となります。
235         </para>
237         <para>
238             Flex の <acronym>MXML</acronym> ファイルで、
239             RemoteObject をサービスにバインドしなければなりません。
240             <acronym>MXML</acronym> で次のように記述します。
241         </para>
243         <programlisting language="xml"><![CDATA[
244 <mx:RemoteObject id="myservice"
245     fault="faultHandler(event)"
246     showBusyCursor="true"
247     destination="zend">
248 ]]></programlisting>
250         <para>
251             ここでは、新しいリモートオブジェクトに "myservice" という名前をつけ、
252             さきほど <filename>services-config.xml</filename> で定義した "zend"
253             にそれをバインドしています。ActionScript からメソッドをコールするには、
254             "myservice.&lt;method&gt;" とするだけです。例を示します。
255         </para>
257         <programlisting language="ActionScript"><![CDATA[
258 myservice.hello("Wade");
259 ]]></programlisting>
261         <para>
262             名前空間を使う場合は
263             "myservice.&lt;namespace&gt;.&lt;method&gt;" のようにします。
264         </para>
266         <programlisting language="ActionScript"><![CDATA[
267 myservice.world.hello("Wade");
268 ]]></programlisting>
270         <para>
271             Flex RemoteObject の実行についてのより詳細な情報は <ulink
272                 url="http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html">
273             Adobe Flex 3 のヘルプサイト</ulink> をごらんください。
274         </para>
275     </sect2>
277     <sect2 id="zend.amf.server.errors">
278         <title>エラー処理</title>
280         <para>
281             デフォルトでは、アタッチしたクラスや関数からスローされた例外はすべて捕捉され、
282             <acronym>AMF</acronym> ErrorMessage として返されます。しかし、この ErrorMessage
283             オブジェクトの中身は、サーバが "production" モード (デフォルトの状態)
284             であるか否かによって異なります。
285         </para>
287         <para>
288             production モードの場合は、例外コードのみが返されます。
289             production モードを無効にする (これはテスト時にしか行ってはいけません)
290             と、例外についての詳細が返されるようになり、
291             例外メッセージや行番号、バックトレースがすべて返されます。
292         </para>
294         <para>
295             production モードを無効にするには、次のようにします。
296         </para>
298         <programlisting language="php"><![CDATA[
299 $server->setProduction(false);
300 ]]></programlisting>
302         <para>
303             再度有効にするには、<constant>TRUE</constant> を渡します。
304         </para>
306         <programlisting language="php"><![CDATA[
307 $server->setProduction(true);
308 ]]></programlisting>
310         <note>
311             <title>production モードの無効化は慎重に!</title>
313             <para>
314                 production モードを無効にするのは、開発時のみにすることを推奨します。
315                 例外メッセージやバックトレースにはシステムに関する重大な情報が含まれる可能性があり、
316                 外部からアクセスされることは好ましくありません。
317                 <acronym>AMF</acronym> はバイナリ形式ではありますが、その仕様は公開されています。
318                 つまり、誰でもメッセージを解読できる可能性があるということです。
319             </para>
320         </note>
322         <para>
323             もうひとつ、特に注意を要するのが <acronym>PHP</acronym> のエラーです。
324             <acronym>INI</acronym> 設定 <emphasis>display_errors</emphasis> が有効になっていると、
325             エラー報告レベルに応じてあらゆる <acronym>PHP</acronym> のエラーが直接出力されてしまいます。
326             これは、<acronym>AMF</acronym> のレスポンスを壊してしまう可能性があります。
327             運用時には <emphasis>display_errors</emphasis> を無効にし、
328             この問題を回避することを推奨します。
329         </para>
330     </sect2>
332     <sect2 id="zend.amf.server.response">
333         <title>AMF レスポンス</title>
335         <para>
336             レスポンスオブジェクトを操作したくなることもあるかもしれません。
337             メッセージヘッダを追加したい場合などが考えられます。サーバの
338             <methodname>handle()</methodname> メソッドはレスポンスオブジェクトを返すので、これが利用できます。
339         </para>
341         <example id="zend.amf.server.response.messageHeaderExample">
342             <title>AMF レスポンスへのメッセージヘッダの追加</title>
344             <para>
345                 この例では、'foo' という MessageHeader に値
346                 'bar' を設定したものをレスポンスに追加してからそれを返します。
347             </para>
349             <programlisting language="php"><![CDATA[
350 $response = $server->handle();
351 $response->addAmfHeader(new Zend_Amf_Value_MessageHeader('foo', true, 'bar'))
352 echo $response;
353 ]]></programlisting>
354         </example>
355     </sect2>
357     <sect2 id="zend.amf.server.typedobjects">
358         <title>型付きオブジェクト</title>
360         <para>
361             <acronym>SOAP</acronym> と同様、
362             <acronym>AMF</acronym> でもクライアントとサーバの間でオブジェクトをやりとりできます。
363             これにより、クライアントとサーバの間での柔軟性と一貫性を確保できます。
364         </para>
366         <para>
367             <classname>Zend_Amf</classname> には、
368             ActionScript と <acronym>PHP</acronym> オブジェクトを関連付けるための 3 つのメソッドが用意されています。
369         </para>
371         <itemizedlist>
372             <listitem>
373                 <para>
374                     まず、サーバ側で明示的なバインドを行うには
375                     <methodname>setClassMap()</methodname> メソッドを使用します。
376                     最初の引数は ActionScript クラス名で、2 番目の引数は関連付ける
377                     <acronym>PHP</acronym> クラス名となります。
378                 </para>
380                 <programlisting language="php"><![CDATA[
381 // ActionScript クラス 'ContactVO' と PHP クラス 'Contact' を関連付けます
382 $server->setClassMap('ContactVO', 'Contact');
383 ]]></programlisting>
384             </listitem>
386             <listitem>
387                 <para>
388                     次に、<acronym>PHP</acronym> クラス内で public プロパティ
389                     <varname>$_explicitType</varname> を設定する方法があります。
390                     ここには、関連付けたい ActionScript クラス名を指定します。
391                 </para>
393                 <programlisting language="php"><![CDATA[
394 class Contact
396     public $_explicitType = 'ContactVO';
398 ]]></programlisting>
399             </listitem>
401             <listitem>
402                 <para>
403                     3 番目の方法として、PHP クラスの public メソッド
404                     <methodname>getASClassName()</methodname> を使用することもできます。
405                     このメソッドは、適切な ActionScript クラスを返すようにしなければなりません。
406                 </para>
408                 <programlisting language="php"><![CDATA[
409 class Contact
411     public function getASClassName()
412     {
413         return 'ContactVO';
414     }
416 ]]></programlisting>
417             </listitem>
418         </itemizedlist>
420         <para>
421             サーバ側で ContactVO を作成したら、
422             サーバオブジェクトに対応するクラスを <acronym>AS3</acronym> で書かなければなりません。
423         </para>
425         <para>
426             Flex プロジェクトの src フォルダを右クリックし、新規作成 ->
427             ActionScript ファイルを選択します。ファイルに ContactVO
428             という名前をつけて終了を押すと、新しいファイルがあらわれます。
429             次のコードをコピーして、クラスを作成しましょう。
430         </para>
432         <programlisting language="as"><![CDATA[
433 package
435     [Bindable]
436     [RemoteClass(alias="ContactVO")]
437     public class ContactVO
438     {
439         public var id:int;
440         public var firstname:String;
441         public var lastname:String;
442         public var email:String;
443         public var mobile:String;
444         public function ProductVO():void {
445         }
446     }
448 ]]></programlisting>
450         <para>
451             このクラスは、同名の <acronym>PHP</acronym> のクラスと構文的に同等となります。
452             変数名はまったく同じで、大文字小文字もあわせておかなければ正しく動作しません。
453             このクラスでは、<acronym>AS3</acronym> 独特のメタタグが 2 つ用いられています。
454             最初のタグは bindable で、これは更新時に change イベントを発火させます。
455             2 番目のタグは RemoteClass で、このクラスがリモートオブジェクトを保持できること、
456             そのエイリアス名が (ここでは) <emphasis>ContactVO</emphasis> であることを定義します。
457             このタグに設定される値は、<acronym>PHP</acronym> のクラスと正確に一致していなければなりません。
458         </para>
460         <programlisting language="as"><![CDATA[
461 [Bindable]
462 private var myContact:ContactVO;
464 private function getContactHandler(event:ResultEvent):void {
465     myContact = ContactVO(event.result);
467 ]]></programlisting>
469         <para>
470             サービスコールの後の result イベントは即時に Flex の ContactVO にキャストされます。
471             myContact にバインドされているすべての内容は、返された
472             ContactVO データで更新されます。
473         </para>
474     </sect2>
476     <sect2 id="zend.amf.server.resources">
477         <title>リソース</title>
479         <para>
480             <classname>Zend_Amf</classname> には、サービスクラスが返すリソース型を
481             ActionScript で使用可能な形式のデータにマッピングするツールが用意されています。
482         </para>
484         <para>
485             リソース型を扱うには、そのリソース名に対応する名前のプラグインクラスを作成する必要があります。
486            クラス名は、リソース名の単語の先頭を大文字化してスペースを除去したものとなり
487             (つまり、リソース型 "mysql result" の場合は MysqlResult となります)、
488             それに何らかのプレフィックスをつけてたとえば <classname>My_MysqlResult</classname>
489             のようになります。このクラスは <methodname>parse()</methodname>
490             メソッドを実装しなければなりません。
491             このメソッドはリソースを引数として受け取り、ActionScript に送信する値を返します。
492             このクラスを記述するファイル名は、クラス名の最後の部分と同じ名前にしなければなりません。
493             たとえば先ほどの例の場合は <filename>MysqlResult.php</filename> となります。
494         </para>
496         <para>
497             リソース用のプラグインを含むディレクトリは、
498             <classname>Zend_Amf</classname> 型ローダーで登録しなければなりません。
499         </para>
501         <programlisting language="php"><![CDATA[
502 Zend_Amf_Parse_TypeLoader::addResourceDirectory(
503     "My",
504     "application/library/resources/My"
506 ]]></programlisting>
508         <para>
509             プラグインのロードに関する詳細は、
510             <link linkend="zend.loader.pluginloader">プラグインローダー</link> を参照ください。
511         </para>
513         <para>
514             <classname>Zend_Amf</classname> リソース用のデフォルトディレクトリは自動的に登録されており、
515             現在ここには "mysql result" リソースおよび "stream" リソースのプラグインが格納されています。
516         </para>
518         <programlisting language="php"><![CDATA[
519 // Example class implementing handling resources of type mysql result
520 class Zend_Amf_Parse_Resource_MysqlResult
522     /**
523      * Parse resource into array
524      *
525      * @param resource $resource
526      * @return array
527      */
528     public function parse($resource) {
529         $result = array();
530         while($row = mysql_fetch_assoc($resource)) {
531             $result[] = $row;
532         }
533         return $result;
534     }
536 ]]></programlisting>
538         <para>
539             未知のリソース型 (つまり、処理用プラグインが存在しない型)
540             を返そうとすると、例外が発生します。
541         </para>
543     </sect2>
545     <sect2 id="zend.amf.server.flash">
546         <title>サーバへの Flash からの接続</title>
548         <para>
549             <classname>Zend_Amf_Server</classname> に Flash プロジェクトから接続する方法は、
550             Flex からの場合とは多少異なります。しかし、いったん接続してしまえば
551             <classname>Zend_Amf_Server</classname> は flex の場合と同じように動作します。
552             次の例は Flex <acronym>AS3</acronym> ファイルからでも使用できます。
553             同じ <classname>Zend_Amf_Server</classname> 設定ファイルを用い、
554             World クラスを用いて接続します。
555         </para>
557         <para>
558             Flash CS を開き、新規 Flash ファイル (ActionScript 3) を作成します。
559             そのドキュメントに <filename>ZendExample.fla</filename> という名前をつけ、
560             このサンプルを使用するフォルダに保存します。
561             次に、同じディレクトリに新規 <acronym>AS3</acronym> ファイルを作成し、
562             <filename>Main.as</filename> という名前をつけます。
563             そして両方のファイルをエディタで開きます。
564             これから、ドキュメントクラスを通じてふたつのファイルをつないできます。
565             ZendExample を選択し、ステージ上でクリックします。
566             ステージのプロパティパネルで、ドキュメントクラスを Main に変更します。
567             これで、ActionScript ファイル <filename>Main.as</filename> が
568             <filename>ZendExample.fla</filename> のユーザインターフェイスとつながります。
569             Flash ファイル ZendExample を実行すると、
570             <filename>Main.as</filename> クラスが実行されるようになるのです。
571             次に、<acronym>AMF</acronym> をコールする ActionScript を追加します。
572         </para>
574         <para>
575             それでは、Main クラスを作成していきましょう。
576             これを用いてデータをサーバに送信し、結果を表示します。
577             次のコードを <filename>Main.as</filename> にコピーしましょう。これから、
578             このコードの中身を追いかけながら何をやっているのかを説明していきます。
579         </para>
581         <programlisting language="as"><![CDATA[
582 package {
583   import flash.display.MovieClip;
584   import flash.events.*;
585   import flash.net.NetConnection;
586   import flash.net.Responder;
588   public class Main extends MovieClip {
589     private var gateway:String = "http://example.com/server.php";
590     private var connection:NetConnection;
591     private var responder:Responder;
593     public function Main() {
594       responder = new Responder(onResult, onFault);
595       connection = new NetConnection;
596       connection.connect(gateway);
597     }
599     public function onComplete( e:Event ):void{
600       var params = "Sent to Server";
601       connection.call("World.hello", responder, params);
602     }
604     private function onResult(result:Object):void {
605       // Display the returned data
606       trace(String(result));
607     }
608     private function onFault(fault:Object):void {
609       trace(String(fault.description));
610     }
611   }
613 ]]></programlisting>
615         <para>
616             まず、さまざまな作業をするための ActionScript ライブラリをインポートする必要があります。
617             ひとつめが NetConnection で、これはクライアントとサーバの間でパイプのような働きをします。
618             もうひとつは Responder オブジェクトで、
619             これはコールが成功したかどうかなどのサーバからの返り値を処理します。
620         </para>
622         <programlisting language="as"><![CDATA[
623 import flash.net.NetConnection;
624 import flash.net.Responder;
625 ]]></programlisting>
627         <para>
628             クラスの中で 3 つの変数を用意します。これらがそれぞれ NetConnection、Responder
629             そして <classname>Zend_Amf_Server</classname> へのゲートウェイ
630             <acronym>URL</acronym> をあらわします。
631         </para>
633         <programlisting language="as"><![CDATA[
634 private var gateway:String = "http://example.com/server.php";
635 private var connection:NetConnection;
636 private var responder:Responder;
637 ]]></programlisting>
639         <para>
640             Main のコンストラクタでレスポンダを作成し、また
641             <classname>Zend_Amf_Server</classname> エンドポイントへの新規接続も作成します。
642             レスポンダでは、サーバからのレスポンスを処理するメソッドが 2 つ定義されています。
643             わかりやすくするため、それぞれ onResult および onFault と名づけます。
644         </para>
646         <programlisting language="as"><![CDATA[
647 responder = new Responder(onResult, onFault);
648 connection = new NetConnection;
649 connection.connect(gateway);
650 ]]></programlisting>
652         <para>
653             onComplete 関数は、コンストラクタの処理が終わった直後に実行されます。
654             ここで、データをサーバに送信します。
655             <classname>Zend_Amf_Server</classname> World->hello 関数をコールするコードを 1 行追加しています。
656         </para>
658         <programlisting language="as"><![CDATA[
659 connection.call("World.hello", responder, params);
660 ]]></programlisting>
662         <para>
663             responder を作成した際に、サーバからのレスポンスを処理する関数として
664             onResult と onFault を定義しました。サーバから正しい結果が返ってきたとき用の関数を追加します。
665             成功時のイベントハンドラは、サーバへの接続が正しく処理されるたびに毎回実行されます。
666         </para>
668         <programlisting language="as"><![CDATA[
669 private function onResult(result:Object):void {
670     // Display the returned data
671     trace(String(result));
673 ]]></programlisting>
675         <para>
676             onFault 関数は、サーバから無効な結果が返ってきたときにコールされます。
677             たとえば、サーバからエラーが返された場合、サーバへの <acronym>URL</acronym> が無効な場合、
678             リモート側にサービスやメソッドが存在しない場合など、
679             接続時に問題が発生した場合にコールされることになります。
680         </para>
682         <programlisting language="as"><![CDATA[
683 private function onFault(fault:Object):void {
684     trace(String(fault.description));
686 ]]></programlisting>
688         <para>
689             これで、ActionScript 内でのリモート接続処理は完成しました。
690             ZendExample を実行すると、 <classname>Zend_Amf</classname> へ接続されるようになります。
691             ここまでを振り返ってみましょう。まず最初にリモートサーバへの接続に必要な変数を追加し、
692             サーバからのレスポンスを受け取ったときに使用するメソッドを定義し、
693             そして最後に返された結果を <methodname>trace()</methodname> で出力しました。
694         </para>
696     </sect2>
698     <sect2 id="zend.amf.server.auth">
699         <title>認証</title>
701         <para>
702             <classname>Zend_Amf_Server</classname> では、認証と認可のフックを指定して
703             サービスへのアクセスを制御できます。この仕組みは、
704             <link linkend="zend.auth"><classname>Zend_Auth</classname></link> および
705             <link linkend="zend.acl"><classname>Zend_Acl</classname></link>
706             コンポーネントが提供するものを使用しています。
707         </para>
709         <para>
710             認証を定義するには、抽象クラス
711             <classname>Zend_Amf_Auth_Abstract</classname> を継承した認証アダプタを作成します。
712             このアダプタは、通常の
713             <link linkend="zend.auth.introduction.adapters">認証アダプタ</link>
714             と同様に <methodname>authenticate()</methodname> メソッドを実装しなければなりません。
715         </para>
717         <para>
718             アダプタでの認証の際には、親クラス
719             <classname>Zend_Amf_Auth_Abstract</classname> のプロパティ
720             <emphasis>_username</emphasis> および
721             <emphasis>_password</emphasis> を使用しなければなりません。
722             <acronym>AMF</acronym> リクエストヘッダに認証情報が含まれていれば、
723             <methodname>authenticate()</methodname> がコールされる前にサーバが
724             <methodname>setCredentials()</methodname> メソッドを用いてその情報を設定します。
725         </para>
727         <para>
728             アダプタが返す識別情報は、<emphasis>role</emphasis>
729             プロパティを含むオブジェクトでなければなりません。
730             これを用いて <acronym>ACL</acronym> アクセス制御が動作します。
731         </para>
733         <para>
734             認証に失敗した場合はそれ以降のリクエストの処理は行われず、
735             失敗したというメッセージとその理由を結果として返します。
736         </para>
738         <para>
739             アダプタとサーバを関連づけるには <methodname>setAuth()</methodname> メソッドを使用します。
740         </para>
742         <programlisting language="php"><![CDATA[
743 $server->setAuth(new My_Amf_Auth());
744 ]]></programlisting>
746         <para>
747             アクセス制御を行うには
748             <methodname>setAcl()</methodname> メソッドで設定した
749             <classname>Zend_Acl</classname> オブジェクトを使用します。
750         </para>
752         <programlisting language="php"><![CDATA[
753 $acl = new Zend_Acl();
754 createPermissions($acl); // パーミッション情報を作成します
755 $server->setAcl($acl);
756 ]]></programlisting>
758         <para>
759             <acronym>ACL</acronym> オブジェクトが設定され、コールされるクラスで
760             <methodname>initAcl()</methodname> メソッドが定義されていれば、
761             <acronym>ACL</acronym> オブジェクトを引数としてこのメソッドがコールされます。
762             このクラスは追加の <acronym>ACL</acronym> ルールを作成して
763             <constant>TRUE</constant> を返すこともできますし、
764             このクラスでのアクセス制御が不要な場合は
765             <constant>FALSE</constant> を返すこともできます。
766         </para>
768         <para>
769             <acronym>ACL</acronym> の準備が終わると、
770             サーバ側で「指定されたロールで、指定されたクラス (関数コールの際は null)
771             のリソース、指定された関数の実行権限があるかどうか」を調べます。
772             認証情報が提供されていない場合は
773             <emphasis>anonymous</emphasis> ロールが定義されているかどうかを調べ、
774             定義されている場合はそれを使用します。定義されていない場合はアクセスを拒否します。
775         </para>
777         <programlisting language="php"><![CDATA[
778 if($this->_acl->isAllowed($role, $class, $function)) {
779     return true;
780 } else {
781     require_once 'Zend/Amf/Server/Exception.php';
782     throw new Zend_Amf_Server_Exception("Access not allowed");
784 ]]></programlisting>
786     </sect2>
788 </sect1>
789 <!--
790 vim:se ts=4 sw=4 et: