自動検出

自動検出導入

Zend Frameworkの中で実装されるSOAP機能は、 すべてのステップをより単純なSOAP通信のために必要とされるようにすることを目的とします。

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

Zend Frameworkが利用されるかもしれないSOAPアプリケーションのために、 3種類の構成があります:

  1. SOAPサーバー PHPのアプリケーション <---> SOAPクライアント PHPのアプリケーション
  2. SOAPサーバー PHPではないアプリケーション <---> SOAPクライアント PHPのアプリケーション
  3. SOAPサーバー PHPのアプリケーション <---> SOAPクライアント PHPではないアプリケーション

SOAPサーバーで提供される機能を常に知っていなければなりません。 WSDLは ネットワーク・サービスAPIを詳細に記述するために使われます。

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

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

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

SOAPサーバー・アプリケーションのためにZend Frameworkを使う2つの方法があります:

  • 分離されたクラスを使用

  • 関数のセットを使用

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

Zend_Soap_AutoDiscoverクラスも、 PHPからXSD型までデータ型マッピングをサポートします。

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

class My_SoapServer_Class {
...
}

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('My_SoapServer_Class');
$autodiscover->handle();

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

Zend_Soap_AutodiscoverはSOAPサーバーではありません

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

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

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();
}

クラスの自動検出

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

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('My_SoapServer_Class');
$autodiscover->handle();

WSDL生成の間、以下の規則が使われます:

  • 生成されたWSDLは、RPCスタイルのウェブサービスを記述します。

  • クラス名が、記述されているウェブサービスの名前として使われます。

  • 'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']が WSDLをデフォルトで利用できるURIとして使われます、 しかし、それはsetUri()メソッドによって上書きできます。

    それは、名前(記述された複雑な型を含む)に関連したすべてのサービスのための ターゲット名前空間としても使われます。

  • クラス・メソッドは、1つのポートタイプに 結び付けられます。

    $className . 'Port'はポートタイプ名として使われます。

  • 各々のクラス・メソッドは、対応するポート操作として登録されます。

  • 各々のメソッド・プロトタイプは、対応するリクエスト/レスポンスメッセージを生成します。

    いくつかのメソッド・パラメータがオプションならば、 メソッドはいくつかのプロトタイプを持つかもしれません。

重要!

WSDL自動検出では、パラメータを決定して型を返すために、 開発者により提供されるPHP docblockを利用します。 実際、スカラー型にとっては、パラメータ型を決定する唯一の方法です。 そして、戻り型にとっては、それらを決定する唯一の方法です。

つまり、正しくて詳細で完全なdocblockを提供することは習慣というだけではなく、 発見するクラスのために必要です。

関数の自動検出

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

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->addFunction('function1');
$autodiscover->addFunction('function2');
$autodiscover->addFunction('function3');
...
$autodiscover->handle();

WSDL生成の間、以下の規則が使われます:

  • 生成されたWSDLは、RPCスタイルのウェブサービスを記述します。

  • 現在のスクリプト名が、記述されているウェブサービスの名前として使われます。

  • 'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']が WSDLを利用できるURIとして使われます。

    それは、名前(記述された複雑な型を含む)に関連したすべてのサービスのための ターゲット名前空間としても使われます。

  • 関数は、1つのポートタイプに 結び付けられます。

    $functionName . 'Port'はポートタイプ名として使われます。

  • 各々の関数は、対応するポート操作として登録されます。

  • 各々の関数プロトタイプは、対応するリクエスト/レスポンスメッセージを生成します。

    いくつかのメソッド・パラメータがオプションなら、 関数はいくつかのプロトタイプを持つかもしれません。

重要!

WSDL自動検出では、パラメータを決定して、型を返すために、 開発者により提供されるPHP docblockを利用します。 実際、スカラー型にとっては、パラメータ型を決定する唯一の方法です。 そして、戻り型にとっては、それらを決定する唯一の方法です。

つまり、正しくて詳細で完全なdocblockを提供することは習慣というだけではなく、 発見するクラスのために必要です。

データ型の自動検出

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

  • PHP文字列 <-> xsd:string

  • PHP integer <-> xsd:int

  • PHP floatおよびdouble値 <-> xsd:float

  • PHPブール値 <-> xsd:boolean

  • PHP配列 <-> soap-enc:Array

  • PHPオブジェクト <-> xsd:struct

  • PHPクラス <-> 複雑な型のストラテジーに基づいた (このセクション参照) [29]

  • type[] または object[] (例えば int[]) <-> 複雑な型のストラテジーに基づいた

  • PHP void <-> 空の型

  • なんらかの理由でこれらの型のいずれとも型が一致しなければ、xsd:anyTypeが使われます。

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

WSDLバインディングスタイル

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

$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();


[29] Zend_Soap_AutoDiscoverは複雑な型のための検出アルゴリズムとして Zend_Soap_Wsdl_Strategy_DefaultComplexTypeクラスで生成されます。 AutoDiscoverコンストラクタの最初のパラメータは、 Zend_Soap_Wsdl_Strategy_Interfaceを実装した、 どんな複雑な型ストラテジーでも、クラスの名前を持つ文字列でもとります。 $extractComplexTypeとの後方互換性のために、 ブール変数はZend_Soap_Wsdlのように解析されます。 詳しくは複雑な型を追加することについて Zend_Soap_Wsdlマニュアルをご覧下さい。