0

サーバ:

import soaplib
from soaplib.core.service import rpc, DefinitionBase
from soaplib.core.model.primitive import String, Integer
from soaplib.core.server import wsgi
from soaplib.core.model.clazz import Array


class HelloWorldService(DefinitionBase):
   @soap(String,Integer,_returns=Array(String))
   def say_hello(self,name,times):
      results = []
      for i in range(0,times):
         results.append('Hello, %s'%name)
      return results

if __name__=='__main__':
   try:
        from wsgiref.simple_server import make_server
        soap_application = soaplib.core.Application([HelloWorldService], 'tns')
        wsgi_application = wsgi.Application(soap_application)
        server = make_server('173.252.236.136', 7789, wsgi_application)
        server.serve_forever()
   except ImportError:
        print "Error: example server code requires Python >= 2.5"

PHP:

$client=new SoapClient("http://173.252.236.136:7789/?wsdl");
try{
ini_set('default_socket_timeout', 5);
var_dump($client->say_hello("Dave", 5));
echo("<br />");
//print_r($client->add(1,2));
}catch(Exception $e){
 echo $e->__toString();
 ini_restore('default_socket_timeout');
}

PHP コードを実行すると、以下の情報が報告されます。

SoapFault exception: [senv:Server] range() integer end argument expected, got NoneType.     in E:\web\webservice\client.php:6 Stack trace: #0 E:\web\webservice\client.php(6): SoapClient->__call('say_hello', Array) #1 E:\web\webservice\client.php(6): SoapClient->say_hello('Dave', 5) #2 {main}

しかし、Python のクライアントを使用して動作します。

from suds.client import Client
hello_client = Client('http://173.252.236.136:7789/?wsdl')
result = hello_client.service.say_hello("Dave", 5)
print result

パラメータnameを送信できずtimes、PHP クライアントを使用して Python サーバーに送信できないことがわかりました。

4

2 に答える 2

0

問題は、soaplibパラメーターと戻り値を Soap-structs でラップすることだと思います。次の出力を見るとわかります。

 var_dump($client->__getFunctions());
 var_dump($client->__getTypes());

したがって、解決策は構造を提供することです:

class SayHelloStruct {
    function __construct($name, $times) {
        $this->name = $name;
        $this->times = $times;
    }
}

$struct = new SayHelloStruct("Dave", 5);
// here "say_hello" is not the method name but the name of the struct
$soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "say_hello");
$param = new SoapParam($soapstruct, "say_hello");

var_dump($client->say_hello($param));

ハッシュ配列をオブジェクトにキャストすることで、それを少し短縮できます。

$struct = (object)array("name" => "Dave", "times" => 5);
// here "say_hello" is not the method name but the name of the struct
$soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "say_hello");
$param = new SoapParam($soapstruct, "say_hello");

var_dump($client->say_hello($param));

-thingSoapParamは最終的には必要ありません。それを壊さずに省略できます。

正直なところ、サーバー側またはクライアント側のフラグのような、より良い解決策があるかどうかはわかりません。

于 2012-07-19T11:44:03.380 に答える