<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 24249 -->
<sect1 id="zend.soap.autodiscovery">
    <title>自動検出</title>

    <sect2 id="zend.soap.autodiscovery.introduction">
        <title>自動検出導入</title>
        <para>
            Zend Frameworkの中で実装される<acronym>SOAP</acronym>機能は、
            すべてのステップをより単純な<acronym>SOAP</acronym>通信のために必要とされるようにすることを目的とします。
        </para>

        <para>
            <acronym>SOAP</acronym>は言語に依存しないプロトコルです。
            そのため、<acronym>PHP</acronym>から<acronym>PHP</acronym>への通信だけのために使われないかもしれません。
        </para>

        <para>
            Zend Frameworkが利用されるかもしれない<acronym>SOAP</acronym>アプリケーションのために、
            ３種類の構成があります:
            <orderedlist>
                <listitem>
                    <simpara><acronym>SOAP</acronym>サーバー <acronym>PHP</acronym>のアプリケーション &lt;---&gt; <acronym>SOAP</acronym>クライアント <acronym>PHP</acronym>のアプリケーション</simpara>
                </listitem>
                <listitem>
                    <simpara><acronym>SOAP</acronym>サーバー <acronym>PHP</acronym>ではないアプリケーション &lt;---&gt; <acronym>SOAP</acronym>クライアント <acronym>PHP</acronym>のアプリケーション</simpara>
                </listitem>
                <listitem>
                    <simpara><acronym>SOAP</acronym>サーバー <acronym>PHP</acronym>のアプリケーション &lt;---&gt; <acronym>SOAP</acronym>クライアント <acronym>PHP</acronym>ではないアプリケーション</simpara>
                </listitem>
            </orderedlist>
        </para>

        <para>
            <acronym>SOAP</acronym>サーバーで提供される機能を常に知っていなければなりません。
            <ulink url="http://www.w3.org/TR/wsdl">WSDL</ulink>は
            ネットワーク・サービス<acronym>API</acronym>を詳細に記述するために使われます。
        </para>

        <para>
            WSDL言語は、十分に複雑です。
            (詳しくは<ulink url="http://www.w3.org/TR/wsdl">http://www.w3.org/TR/wsdl</ulink>をご覧下さい)
            そのため、WSDLの正しい説明を用意することは困難です。
        </para>

        <para>
            もう一つの問題は、すでに既存のWSDLの変化をネットワーク・サービス<acronym>API</acronym>で同期することです。
        </para>

        <para>
            両方の問題は、WSDL自動生成によって解決されるかもしれません。
            この必要条件は、<acronym>SOAP</acronym>サーバー自動検出です。
            それは<acronym>SOAP</acronym>サーバー・アプリケーションで使われる、
            オブジェクトに類似したオブジェクトを組み立て、
            必要な情報を引き出して、この情報を使う正しいWSDLを生成します。
        </para>

        <para>
            <acronym>SOAP</acronym>サーバー・アプリケーションのためにZend Frameworkを使う２つの方法があります:
            <itemizedlist>
                <listitem>
                    <para>分離されたクラスを使用</para>
                </listitem>
                <listitem>
                    <para>関数のセットを使用</para>
                </listitem>
            </itemizedlist>
        </para>

        <para>
            両方のメソッドは、Zend Framework 自動検出機能によってサポートされます。
        </para>

        <para>
            <classname>Zend_Soap_AutoDiscover</classname>クラスも、
            <acronym>PHP</acronym>から<ulink url="http://www.w3.org/TR/xmlschema-2/">XSD型</ulink>までデータ型マッピングをサポートします。
        </para>

        <para>
            これは自動検出機能の一般的な用法の例です。
            <methodname>handle()</methodname>関数はWSDLファイルを生成してブラウザーにポストします。
        </para>

        <programlisting language="php"><![CDATA[
class My_SoapServer_Class {
...
}

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('My_SoapServer_Class');
$autodiscover->handle();
]]></programlisting>

        <para>
            ファイルまたは<acronym>XML</acronym>ストリングとして保存するために生成されたWSDLファイルへのアクセスも必要ならば、
            AutoDiscoverクラスが提供する<methodname>dump($filename)</methodname>または<methodname>toXml()</methodname>関数を使えます。
        </para>

        <note id="zend.soap.autodiscovery.introduction.noserver">
            <title>Zend_Soap_AutodiscoverはSOAPサーバーではありません</title>

            <para>
                クラス<classname>Zend_Soap_AutoDiscover</classname>が
                単独で<acronym>SOAP</acronym>サーバーの働きをしない点に注意することは、非常に重要です。
                それはWSDLを生成して、それがリスンしているurlにアクセスした誰にでも届けるだけです。
            </para>

            <para>
                <acronym>SOAP</acronym>エンドポイントUriがデフォルト値、
                <code>'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']</code>
                を使いますが、
                しかしこれは<methodname>setUri()</methodname>関数や
                <classname>Zend_Soap_AutoDiscover</classname>クラスのコンストラクタのパラメータで変更できます。
                このエンドポイントではリクエストをリスンする
                <classname>Zend_Soap_Server</classname>クラスを準備しなくてはいけません。
            </para>

            <programlisting language="php"><![CDATA[
if(isset($_GET['wsdl'])) {
    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('HelloWorldService');
    $autodiscover->handle();
} else {
    //ここで現行ファイルを指示します。
    $soap = new Zend_Soap_Server("http://example.com/soap.php?wsdl");
    $soap->setClass('HelloWorldService');
    $soap->handle();
}
]]></programlisting>
        </note>
    </sect2>

    <sect2 id="zend.soap.autodiscovery.class">
        <title>クラスの自動検出</title>

        <para>
            クラスが<acronym>SOAP</acronym>サーバー機能を提供することに使われるならば、
            同じクラスはWSDL生成のために<classname>Zend_Soap_AutoDiscover</classname>に提供されなければなりません:
        </para>

        <programlisting language="php"><![CDATA[
$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('My_SoapServer_Class');
$autodiscover->handle();
]]></programlisting>

        <para>
            WSDL生成の間、以下の規則が使われます:
            <itemizedlist>
                <listitem>
                    <para>生成されたWSDLは、RPCスタイルのウェブサービスを記述します。</para>
                </listitem>
                <listitem>
                    <para>クラス名が、記述されているウェブサービスの名前として使われます。</para>
                </listitem>
                <listitem>
                    <para>
                        <code>'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']</code>が
                        WSDLをデフォルトで利用できる<acronym>URI</acronym>として使われます、
                        しかし、それは<methodname>setUri()</methodname>メソッドによって上書きできます。
                    </para>
                    <para>
                        それは、名前（記述された複雑な型を含む）に関連したすべてのサービスのための
                        ターゲット名前空間としても使われます。
                    </para>
                </listitem>
                <listitem>
                    <para>
                        クラス・メソッドは、１つの<ulink url="http://www.w3.org/TR/wsdl#_porttypes">ポートタイプ</ulink>に
                        結び付けられます。
                    </para>
                    <para>
                        <code>$className . 'Port'</code>はポートタイプ名として使われます。
                    </para>
                </listitem>
                <listitem>
                    <para>各々のクラス・メソッドは、対応するポート操作として登録されます。</para>
                </listitem>
                <listitem>
                    <para>各々のメソッド・プロトタイプは、対応するリクエスト/レスポンスメッセージを生成します。</para>
                    <para>いくつかのメソッド・パラメータがオプションならば、
                    メソッドはいくつかのプロトタイプを持つかもしれません。</para>
                </listitem>
            </itemizedlist>
        </para>

        <note>
            <title>重要!</title>
            <para>
                WSDL自動検出では、パラメータを決定して型を返すために、
                開発者により提供される<acronym>PHP</acronym> docblockを利用します。
                実際、スカラー型にとっては、パラメータ型を決定する唯一の方法です。
                そして、戻り型にとっては、それらを決定する唯一の方法です。
            </para>
            <para>
                つまり、正しくて詳細で完全なdocblockを提供することは習慣というだけではなく、
                発見するクラスのために必要です。
            </para>
        </note>
    </sect2>

    <sect2 id="zend.soap.autodiscovery.functions">
        <title>関数の自動検出</title>

        <para>
            関数のセットが<acronym>SOAP</acronym>サーバー機能を提供することに使われるならば、
            同じセットはWSDL生成のために<classname>Zend_Soap_AutoDiscovery</classname>に提供されなければなりません:
        </para>

        <programlisting language="php"><![CDATA[
$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->addFunction('function1');
$autodiscover->addFunction('function2');
$autodiscover->addFunction('function3');
...
$autodiscover->handle();
]]></programlisting>

        <para>
            WSDL生成の間、以下の規則が使われます:
            <itemizedlist>
                <listitem>
                    <para>生成されたWSDLは、RPCスタイルのウェブサービスを記述します。</para>
                </listitem>
                <listitem>
                    <para>現在のスクリプト名が、記述されているウェブサービスの名前として使われます。</para>
                </listitem>
                <listitem>
                    <para>
                        <code>'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']</code>が
                        WSDLを利用できる<acronym>URI</acronym>として使われます。
                    </para>
                    <para>
                        それは、名前（記述された複雑な型を含む）に関連したすべてのサービスのための
                        ターゲット名前空間としても使われます。
                    </para>
                </listitem>
                <listitem>
                    <para>
                        関数は、１つの<ulink url="http://www.w3.org/TR/wsdl#_porttypes">ポートタイプ</ulink>に
                        結び付けられます。
                    </para>
                    <para>
                        <code>$functionName . 'Port'</code>はポートタイプ名として使われます。
                    </para>
                </listitem>
                <listitem>
                    <para>各々の関数は、対応するポート操作として登録されます。</para>
                </listitem>
                <listitem>
                    <para>各々の関数プロトタイプは、対応するリクエスト/レスポンスメッセージを生成します。</para>
                    <para>いくつかのメソッド・パラメータがオプションなら、
                    関数はいくつかのプロトタイプを持つかもしれません。</para>
                </listitem>
            </itemizedlist>
        </para>

        <note>
            <title>重要!</title>
            <para>
                WSDL自動検出では、パラメータを決定して、型を返すために、
                開発者により提供される<acronym>PHP</acronym> docblockを利用します。
                実際、スカラー型にとっては、パラメータ型を決定する唯一の方法です。
                そして、戻り型にとっては、それらを決定する唯一の方法です。
            </para>
            <para>
                つまり、正しくて詳細で完全なdocblockを提供することは習慣というだけではなく、
                発見するクラスのために必要です。
            </para>
        </note>
    </sect2>

    <sect2 id="zend.soap.autodiscovery.datatypes">
        <title>データ型の自動検出</title>

        <para>
            入出力データ型は、以下のマッピングを用いて、ネットワーク・サービス型に変換されます:

            <itemizedlist>
                <listitem>
                    <para><acronym>PHP</acronym>文字列 &lt;-&gt; <code>xsd:string</code></para>
                </listitem>
                <listitem>
                    <para><acronym>PHP</acronym> integer &lt;-&gt; <code>xsd:int</code></para>
                </listitem>
                <listitem>
                    <para><acronym>PHP</acronym> floatおよびdouble値 &lt;-&gt; <code>xsd:float</code></para>
                </listitem>
                <listitem>
                    <para><acronym>PHP</acronym>ブール値 &lt;-&gt; <code>xsd:boolean</code></para>
                </listitem>
                <listitem>
                    <para><acronym>PHP</acronym>配列 &lt;-&gt; <code>soap-enc:Array</code></para>
                </listitem>
                <listitem>
                    <para><acronym>PHP</acronym>オブジェクト &lt;-&gt; <code>xsd:struct</code></para>
                </listitem>
                <listitem>
                    <para>
                        <acronym>PHP</acronym>クラス &lt;-&gt; 複雑な型のストラテジーに基づいた (<link linkend="zend.soap.wsdl.types.add_complex">このセクション</link>参照)
                        <footnote>
                            <para>
                                <classname>Zend_Soap_AutoDiscover</classname>は複雑な型のための検出アルゴリズムとして
                                <classname>Zend_Soap_Wsdl_Strategy_DefaultComplexType</classname>クラスで生成されます。
                                AutoDiscoverコンストラクタの最初のパラメータは、
                                <classname>Zend_Soap_Wsdl_Strategy_Interface</classname>を実装した、
                                どんな複雑な型ストラテジーでも、クラスの名前を持つ文字列でもとります。
                                <code>$extractComplexType</code>との後方互換性のために、
                                ブール変数は<classname>Zend_Soap_Wsdl</classname>のように解析されます。
                                詳しくは<link linkend="zend.soap.wsdl.types.add_complex">複雑な型を追加することについて
                                <classname>Zend_Soap_Wsdl</classname>マニュアル</link>をご覧下さい。
                            </para>
                        </footnote>
                    </para>
                </listitem>
                <listitem>
                    <para>type[] または object[] (例えば int[]) &lt;-&gt; 複雑な型のストラテジーに基づいた</para>
                </listitem>
                <listitem>
                    <para><acronym>PHP</acronym> void &lt;-&gt; 空の型</para>
                </listitem>
                <listitem>
                    <para>なんらかの理由でこれらの型のいずれとも型が一致しなければ、<code>xsd:anyType</code>が使われます。</para>
                </listitem>
            </itemizedlist>

            <code>xsd:</code> が "http://www.w3.org/2001/XMLSchema" ネームスペースであるところでは、
            <code>soap-enc:</code> は "http://schemas.xmlsoap.org/soap/encoding/" ネームスペースで、
            <code>tns:</code> はサービスのための "target namespace" です。
        </para>
    </sect2>

    <sect2 id="zend.soap.autodiscovery.wsdlstyles">
        <title>WSDLバインディングスタイル</title>

        <para>
            WSDLは、異なるトランスポートのメカニズムとスタイルを提供します。
            これは、WSDLのバインディング・セクションの範囲内で、
            <code>soap:binding</code>および<code>soap:body</code>タグに影響を及ぼします。
            クライアント毎に、本当に機能するオプションについて、それぞれの必要条件があります。
            したがって、自動検出クラスでどんな<code>setClass</code>や<code>addFunction</code>メソッドでも呼び出す前に、
            スタイルを設定できます。
        </para>

        <programlisting language="php"><![CDATA[
$autodiscover = new Zend_Soap_AutoDiscover();
// デフォルトは 'use' => 'encoded' 及び
// 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/' です。
$autodiscover->setOperationBodyStyle(
                    array('use' => 'literal',
                          'namespace' => 'http://framework.zend.com')
                );

// デフォルトは 'style' => 'rpc' 及び
// 'transport' => 'http://schemas.xmlsoap.org/soap/http' です。
$autodiscover->setBindingStyle(
                    array('style' => 'document',
                          'transport' => 'http://framework.zend.com')
                );
...
$autodiscover->addFunction('myfunc1');
$autodiscover->handle();
]]></programlisting>
    </sect2>
</sect1>
