简体   繁体   English

如何使用 WSDL 模式使用 PHP 使用 Web 服务

[英]How to consume a webservice with PHP using WSDL mode

I'm trying to consume a webservice using PHP.我正在尝试使用 PHP 使用 Web 服务。

This is the code I have:这是我的代码:

<?php

ini_set('soap.wsdl_cache_enabled', false);

class SayHelloResponse
{
    public $sayHelloResult;
    public $greeting;
}

$client = new SoapClient(
    'http://localhost:8000/greetings_server.php?wsdl', [
        'trace' => 1,
        'soap_version' => SOAP_1_2,
        'classmap' => [
            'sayHelloResponse' => SayHelloResponse::class,
        ]
    ]);

if ($argc === 1) {
    echo "Service description:" . PHP_EOL;
    echo "--------------------" . PHP_EOL;
    echo "Functions:" . PHP_EOL;
    print_r($client->__getFunctions());
    echo "=====" . PHP_EOL;
    echo "Types:" . PHP_EOL;
    print_r($client->__getTypes());
} elseif ($argv[1] == "h") {
    try {
        echo "Making the call" . PHP_EOL;
        $sayHelloResponse = $client->sayHello(
            [
                'name' => $argv[2]
            ]);

        var_dump($sayHelloResponse);
        var_dump($client->__getLastResponse());
    } catch (SoapFault $exception) {
        echo "Error: " . $exception->getMessage() . PHP_EOL;
        var_dump($client->__getLastRequest());
        var_dump($client->__getLastResponse());
    }
} else {
    echo $client->sayGoodBye($argv[2]);
}

When I run the script without any CLI arguments I get:当我在没有任何 CLI 参数的情况下运行脚本时,我得到:

Service description:
--------------------
Functions:
Array
(
    [0] => sayHelloResponse sayHello(sayHello $parameters)
    [1] => sayGoodByeResponse sayGoodBye(sayGoodBye $parameters)
)
=====
Types:
Array
(
    [0] => struct sayHello {
 string name;
}
    [1] => struct sayHelloResponse {
 string sayHelloResult;
}
    [2] => struct sayGoodBye {
 string name;
}
    [3] => struct sayGoodByeResponse {
 string sayGoodByeResult;
}
)

Then, when I run it with php greetings.php h Mauro I get:然后,当我使用php greetings.php h Mauro运行它时,我得到:

Making the call
object(SayHelloResponse)#2 (2) {
  ["sayHelloResult"]=>
  NULL
  ["greeting"]=>
  NULL
}
string(559) "<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="urn:Greetings" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://www.w3.org/2003/05/soap-encoding"><env:Body xmlns:rpc="http://www.w3.org/2003/05/soap-rpc"><ns1:sayHelloResponse env:encodingStyle="http://www.w3.org/2003/05/soap-encoding"><rpc:result>greeting</rpc:result><greeting xsi:type="xsd:string">Hello Mauro!</greeting></ns1:sayHelloResponse></env:Body></env:Envelope>
"

So I can see the result I'm looking for is right there ( Hello Mauro! ), I just don't know how to access it :(所以我可以看到我正在寻找的结果就在那里( Hello Mauro! ),我只是不知道如何访问它:(

The thing is, if I try to use the webservice in non-wsdl mode it works fine but I need to use the WSDL (Which I'm generating at the other end with another PHP script).问题是,如果我尝试在非 wsdl 模式下使用 web 服务,它可以正常工作,但我需要使用 WSDL(我在另一端使用另一个 PHP 脚本生成)。

And, if you're wondering, the WSDL seems to be fine as I checked it with SoapUI.而且,如果您想知道,当我使用 SoapUI 检查它时,WSDL 似乎很好。

Thanks for your help谢谢你的帮助

-- --

Edit:编辑:

I tried this little python script:我试过这个小python脚本:

from zeep import Client
client = Client('http://localhost:8000/greetings_server.php?wsdl')
result = client.GreetingsService.sayHello('Mauro')

And when I run it I get:当我运行它时,我得到:

Traceback (most recent call last):
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/types/complex.py", line 206, in parse_xmlelement
    result = element.parse_xmlelements(
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/elements/indicators.py", line 617, in parse_xmlelements
    item_subresult = element.parse_xmlelements(
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/elements/element.py", line 206, in parse_xmlelements
    raise UnexpectedElementError(
zeep.exceptions.UnexpectedElementError: Unexpected element 'greeting', expected 'sayHelloResult'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/proxy.py", line 46, in __call__
    return self._proxy._binding.send(
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 135, in send
    return self.process_reply(client, operation_obj, response)
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 231, in process_reply
    result = operation.process_reply(doc)
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 430, in process_reply
    return self.output.deserialize(envelope)
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/messages/soap.py", line 101, in deserialize
    body_result = self._deserialize_body(body)
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/wsdl/messages/soap.py", line 442, in _deserialize_body
    result = self.body.parse(xmlelement, self.wsdl.types, context=context)
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/elements/element.py", line 126, in parse
    return xsd_type.parse_xmlelement(
  File "/home/mauro/.local/lib/python3.8/site-packages/zeep/xsd/types/complex.py", line 212, in parse_xmlelement
    raise XMLParseError(exc.message)
zeep.exceptions.XMLParseError: Unexpected element 'greeting', expected 'sayHelloResult'

From this I get that there is a mismatch between the WSDL and the response the server is returning... I checked an older version of the greetings.wsdl file and found this misterious "greeting" element.由此我得知 WSDL 与服务器返回的响应之间存在不匹配...我检查了较旧版本的 greetings.wsdl 文件并发现了这个神秘的“问候”元素。 I guess there must be a cache issue but I can't put my finger on it.我想一定有缓存问题,但我无法解决。

The python library I'm using is this我正在使用的python库是这个

I finally got my answer... It was a difficult one and I'm not even sure how I spotted it but the problem was in the WSDL definition.我终于得到了答案……这是一个困难的答案,我什至不确定我是如何发现它的,但问题出在 WSDL 定义中。

More specifically, the binding style was wrong (or at least not compatible with the client I was using).更具体地说,绑定样式是错误的(或者至少与我使用的客户端不兼容)。

The original one was document and I needed it to be rpc .原始文件是document ,我需要它是rpc

Once I made that little change everything worked as expected.一旦我做了那个小小的改变,一切都按预期工作。

I'm leaving a reference to my code for someone else looking at it.我要为其他人留下对我的代码的引用

Edit: for the record, this site's example was the one that tipped me off :)编辑:为了记录, 这个网站的例子是给我提示的那个:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM