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

我发现我无法使用 PHP 客户端将参数发送nametimesPython 服务器。

4

2 回答 2

1

我遇到了这个问题。如果要将参数传递给 python webservice。你只需要传递一个数组作为参数。像这样:

var_dump($client->say_hello(array("name"=>"Dave","times"=>5)));

于 2014-09-05T08:15:45.067 回答
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 回答