「PHP から SOAP 経由でサービスをよんでね」とか言われたのですが,PHP は使ったことがないのですよ...orz
とりあえず調べてみると,PEAR にベータ版だが SOAP モジュールがあるのでこれを使うことにします.
基本的な使い方は以下のサイトで紹介されています.
- http://blogs.wankuma.com/katamari/archive/2007/12/09/112281.aspx
- http://www.s-koichi.info/blog/archives/2008/01/08/2315-005421.php
ただねー,「これ使って」と渡された WSDL ファイルを SOAP_WSDL が正しく解釈してくれない...orz
どっちが悪いんだろうか.
仕方がないので SOAP_Client の方でがんばることに.
ヘッダに情報を追加する
Client.php や Value.php あたりのコードを読んで「こんな感じか?」と作ってみた.
<?php require_once('SOAP/Client.php'); $client = new SOAP_Client('http://localhost:8080'); $header = new SOAP_Header( '{http://www.example.com}aaa', false, new SOAP_Value( '{http://www.example.com}bbb', 'string', 'text-value' ) ); $client->addHeader($header); $method = new SOAP_Value( '{http://www.example.com/method}hoge', false, array( 'arg0' => 'hello!', 'arg1' => 1234 ) ); $options = array( 'style' => 'document', 'timeout' => 20 ); $res = $client->call( 'hoge', array('hoge' => $method), $options ); print_r($res); ?>
↓生成された SOAP リクエスト
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns4="http://www.example.com" xmlns:ns5="http://www.example.com/method" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Header> <ns4:aaa xsi:type="xsd:string" SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next" SOAP-ENV:mustUnderstand="0"> <ns4:bbb xsi:type="xsd:string">text-value</ns4:bbb> </ns4:aaa> </SOAP-ENV:Header> <SOAP-ENV:Body> <ns5:hoge> <arg0 xsi:type="xsd:string">hello!</arg0> <arg1 xsi:type="xsd:int">1234</arg1> </ns5:hoge> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
複雑な引数に対応する
いろいろ実験してみる.
<?php require_once('SOAP/Client.php'); $client = new SOAP_Client('http://localhost:8080'); $ns = '{http://www.example.com/method}'; $arg0 = new SOAP_Value( $ns . 'arg0', 'string', 'hello!' ); $arg1 = new SOAP_Value( $ns . 'arg1', false, array( 'item1' => new SOAP_Value( $ns . 'item1', $ns . 'MyType', // ←ここはオリジナルタイプ array( 'value' => new SOAP_Value( $ns . 'value', 'string', 'ほげ' ) ) ), 'item2' => new SOAP_Value( $ns . 'item2', 'string', 'HOGE' ) ) ); $method = new SOAP_Value( $ns . 'hoge', false, array( 'arg0' => $arg0, 'arg1' => $arg1 ) ); $options = array( 'style' => 'document', 'timeout' => 20 ); $res = $client->call( 'hoge', array('hoge' => $method), $options ); print_r($res); ?>
↓生成された SOAP リクエスト
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns4="http://www.example.com/method" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns4:hoge> <ns4:arg0 xsi:type="xsd:string">hello!</ns4:arg0> <ns4:arg1> <ns4:item1 xsi:type="ns4:MyType"> <ns4:value xsi:type="xsd:string">ほげ</ns4:value> </ns4:item1> <ns4:item2 xsi:type="xsd:string">HOGE</ns4:item2> </ns4:arg1> </ns4:hoge> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
自動変換(するはず)
テストしてないので注意!
http://www.pear.php.net/package/SOAP/docs/latest/__filesource/fsource_SOAP__SOAP-0.12.0exampleclient.php.html
を読んでたら「できそうだ」ということがわかった.でもテストしていない.
レスポンスを受けたとき,登録したタイプの要素が含まれていると,デコードした値を対応するクラスのオブジェクトに詰めてくれるっぽい.
http://www.pear.php.net/package/SOAP/docs/latest/__filesource/fsource_SOAP__SOAP-0.12.0Base.php.html
↑の _decode あたり.
<?php require_once('SOAP/Value.php'); function A_Type_QName() { return '{http://www.example.com/type}A_Type'; } class A_Type { var $path; var $list; function __construct($path, $list) { $this->path = $path; $this->list = $list; } function toSoap($top) { $ns = '{http://www.example.com/type}'; $soap = new SOAP_Value( $top, A_Type_QName(), array( 'path' => new SOAP_Value( $ns . 'path', 'string', $this->path ), 'list' => new SOAP_Value( $ns . 'list', 'array', $this->list ) ) ); return $soap; } } ?>
<?php require_once('SOAP/Client.php'); require_once(dirname(__FILE__) . '/a_type.php'); $client = new SOAP_Client('http://localhost:8080'); $client->_auto_translation = true; $client->setTypeTranslation(A_Type_QName(), 'A_Type'); $a_type = new A_Type( '/var/www/html/a_type.php', array( 'name' => 'hoge', 'id' => 1234, 'description' => 'foo' ) ); $ns = '{http://www.example.com/method}'; $methodName = 'ope1'; $method = new SOAP_Value( $ns . $methodName, false, array('arg0' => $a_type->toSoap($ns . 'arg0')) ); $res = $client->call( $methodName, array($methodName => $method), array( 'style' => 'document', 'timeout' => 20 ) ); print_r($res); ?>
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns4="http://www.example.com/type" xmlns:ns5="http://www.example.com/method" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns5:ope1> <ns5:arg0 xsi:type="ns4:A_Type"> <ns4:path xsi:type="xsd:string">/var/www/html/a_type.php</ns4:path> <ns4:list> <name xsi:type="xsd:string">hoge</name> <id xsi:type="xsd:int">1234</id> <description xsi:type="xsd:string">foo</description> </ns4:list> </ns5:arg0> </ns5:ope1> </SOAP-ENV:Body> </SOAP-ENV:Envelope>