PHP SoapServer 和复杂类型
我正在使用 SoapServer 类在 PHP 中构建 Web 服务,但遇到了复杂类型转换的问题。
WSDL 是完全有效的,并且 PHP SoapClient 可以完美地处理它,但是返回的复杂类型似乎没有正确转换。当我在 .Net 中使用该服务时,这一点就暴露出来了,因为我收到了异常,表明该类型不存在于给定的命名空间中。
我多次修改了我的函数,更改了元素上的命名空间,但无论我使用什么命名空间,.Net 都会继续给我错误。
考虑以下脚本缩写:
function getCommands() {
$output = array();
// ...
foreach($result as $row) {
$output[] = new SoapVar($row, SOAP_ENC_OBJECT, 'ns1:command');
}
return $output;
}
缩写响应:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:MyWebService"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getCommandsResponse>
<return SOAP-ENC:arrayType="ns1:command[12]" xsi:type="ns1:ArrayOfCommand">
<item xsi:type="ns1:command">
<!-- ... -->
</item>
<!-- ... -->
</return>
</ns1:getCommandsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我注意到 xmlns:ns1
是通过 WSDL 定义的,并且它确实与 WSDL 中的命名空间匹配。但是,.Net SOAP 客户端似乎不理解其中定义的 command
元素。然而,它确实知道这就是定义 ArrayOfCommand 的地方。
所以我的问题是多部分的:
- 这是 SoapServer 的已知错误吗?
- 如果没有,我的 WSDL 中是否遗漏了一些严重的内容?
- 我没有正确编码我的对象吗?
- 这是 .Net 的问题吗?如果是这样,解决方法是什么?
I am working on building a web service in PHP using the SoapServer class, but I'm running into an issue with casting of complex types.
The WSDL is completely valid, and the PHP SoapClient handles it flawlessly, but there seems to be an issue with the complex types that are returned not being cast properly. This came to light when consuming the service in .Net, as I was getting exceptions that indicated the type was not present in the given namespace.
I mangled my function numerous times, changing the namespace on the element, but .Net continues to give me errors, regardless of what namespace I use.
Consider the following abbreviation of the script:
function getCommands() {
$output = array();
// ...
foreach($result as $row) {
$output[] = new SoapVar($row, SOAP_ENC_OBJECT, 'ns1:command');
}
return $output;
}
The abbreviated response:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:MyWebService"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getCommandsResponse>
<return SOAP-ENC:arrayType="ns1:command[12]" xsi:type="ns1:ArrayOfCommand">
<item xsi:type="ns1:command">
<!-- ... -->
</item>
<!-- ... -->
</return>
</ns1:getCommandsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
What I've noticed is that xmlns:ns1
is defined by way of the WSDL, and it does match the namespace in the WSDL. However, the .Net SOAP client doesn't seem to understand that the command
element is defined there. It does, however, understand that that's where ArrayOfCommand
is defined.
So my question is multipart:
- Is this a known bug with the SoapServer?
- If not, am I missing something grievous in my WSDL?
- Am I not encoding my objects properly?
- Is this an issue with .Net? If so, what's the work-around?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我能够通过使用 Google WSDL 供参考。然后,我必须在 PHP 函数中施展一些魔法,将
$command
的元素转换为适合 WSDL 中各自类型的元素,并将整个命令编码为ns2:command< /代码>。当与 WSDL 保持一致时,这一切都很好地结合在一起,并且 .Net 的难度为零。
我很惊讶开发社区中没有人愿意回答这个问题,但我希望有人能够从中收集到至少一些关于如何解决他们自己的问题实例的指导。
I was able to resolve this issue by working over the
<types/>
section of my WSDL again, using the Google WSDL for reference. Then, I had to work some magic in my PHP function, casting the elements of the$command
appropriate to their respective types in the WSDL, and encoding the entire command as ans2:command
. When aligned with the WSDL, this all fell together nicely and .Net is having zero difficulty with it.I'm surprised nobody in the development community was willing to answer this, but I hope someone will be able to glean from it at least some direction on how to fix their own instance of this problem.