[英]WSDL PHP Soapserver array and complex type request
I have created a soap server in php with PHP Soapserver. 我已经用PHP Soapserver在php中创建了一个肥皂服务器。 I have created a function 'addItems' to add multiple items as an array in the first argument and a corresponding wsdl document.
我创建了一个函数'addItems',将多个项目作为数组添加到第一个参数和相应的wsdl文档中。 In the wsdl I've created an array object 'items' like this:
在wsdl中,我创建了一个数组对象“ items”,如下所示:
<s:complexType name="items">
<s:sequence>
<s:element nillable="true" name="item" type="tns:item" minOccurs="0" maxOccurs="unbounded"/>
</s:sequence>
</s:complexType>
The php function is just a simple class method passed to the php soapserver like this: php函数只是传递给php soapserver的简单类方法,如下所示:
<?php
class Test
{
public function addItems($items) {
print_r($items);
}
}
$service = new Test();
$server = new SoapServer('wsdl.xml');
$server->setObject();
print($server->handle());
The problem it the way php soapserver handles the array. 问题是php soapserver处理数组的方式。 When I add just one item the items list isn't returned as an array.
当我仅添加一项时,项列表不会作为数组返回。 When i add two items the array of items is stored in a an item element instead of the expected items argument.
当我添加两个项目时,项目数组存储在一个项目元素中,而不是预期的项目参数中。
I tried using soapenc:array, but that seems incompatible with WS-I compliance as mentioned in http://www.ws-i.org/Profiles/BasicProfile-1.0-2004-04-16.html#refinement16556272 and also it fails when I want the add the service to visual studio when I use this type of encoding. 我尝试使用soapenc:array,但是这似乎与http://www.ws-i.org/Profiles/BasicProfile-1.0-2004-04-16.html#refinement16556272中提到的WS-I兼容不兼容,并且它也失败了当我想在使用这种类型的编码时将服务添加到Visual Studio中时。
So what I'm doing wrong? 所以我做错了什么? I think i have to change the wsdl somewhere but couldn't find a working example.
我认为我必须在某处更改wsdl,但找不到有效的示例。 Or do I have to set some options for soapserver?
还是我必须为soapserver设置一些选项? I'm lost.
我迷路了。
Below follows the request, actual result and expected result: 以下是请求,实际结果和预期结果:
Request with one item: 要求一件:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:addItems" xmlns:wsdl="http://base.shopzonline.com/soap/api/test/?wsdl">
<soapenv:Header/>
<soapenv:Body>
<urn:addItems>
<items>
<!--Zero or more repetitions:-->
<wsdl:item>
<wsdl:id>1</wsdl:id>
<wsdl:name>a</wsdl:name>
</wsdl:item>
</items>
</urn:addItems>
</soapenv:Body>
</soapenv:Envelope>
actual result for $items argument $ items参数的实际结果
Array
(
[item] => Array
(
[id] => 1
[name] => a
)
)
expected result for $items argument $ items参数的预期结果
Array
[0] => (
Array
(
[id] => 1
[name] => a
)
)
Request with multiple: 请求多个:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:addItems" xmlns:wsdl="http://base.shopzonline.com/soap/api/test/?wsdl">
<soapenv:Header/>
<soapenv:Body>
<urn:addItems>
<items>
<!--Zero or more repetitions:-->
<wsdl:item>
<wsdl:id>1</wsdl:id>
<wsdl:name>a</wsdl:name>
</wsdl:item>
<wsdl:item>
<wsdl:id>2</wsdl:id>
<wsdl:name>b</wsdl:name>
</wsdl:item>
</items>
</urn:addItems>
</soapenv:Body>
</soapenv:Envelope>
actual result for $items argument $ items参数的实际结果
Array
(
[item] => Array
(
[0] => Array
(
[id] => 1
[name] => a
)
[1] => Array
(
[id] => 2
[name] => b
)
)
)
expected result 预期结果
Array
(
[0] => Array
(
[id] => 1
[name] => a
)
[1] => Array
(
[id] => 2
[name] => b
)
)
Below the full WSDL: 在完整的WSDL下面:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions name="LocalhostTestWebservice"
targetNamespace="http://localhost/soap/api/test/?wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://localhost/soap/api/test/?wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
>
<wsdl:types>
<s:schema elementFormDefault="qualified" attributeFormDefault="unqualified" targetNamespace="http://localhost/soap/api/test/?wsdl">
<s:complexType name="addItemsResponseElement">
<s:sequence>
<s:element name="result" minOccurs="0" type="s:int"/>
</s:sequence>
</s:complexType>
<s:element name="addItemsResponseElement" nillable="true" type="tns:addItemsResponseElement" />
<s:complexType name="item">
<s:sequence>
<s:element name="id" type="s:string" />
<s:element name="name" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="item" type="tns:item" />
<s:complexType name="items">
<s:sequence>
<s:element nillable="true" name="item" type="tns:item" minOccurs="0" maxOccurs="unbounded"/>
</s:sequence>
</s:complexType>
<s:element name="items" type="tns:items" />
</s:schema>
</wsdl:types>
<wsdl:message name="addItemsRequest">
<wsdl:part name="items" type="tns:items" />
</wsdl:message>
<wsdl:message name="addItemsResponse">
<wsdl:part name="parameters" type="tns:addItemsResponseElement"/>
</wsdl:message>
<wsdl:portType name="TestPortType">
<wsdl:operation name="addItems">
<wsdl:input message="tns:addItemsRequest" />
<wsdl:output message="tns:addItemsResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="LocalhostTestWebserviceBinding" type="tns:TestPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="addItems">
<soap:operation soapAction="addItems" />
<wsdl:input>
<soap:body use="literal" namespace="urn:addItems" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" namespace="urn:addItems" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="LocalhostTestWebservice">
<wsdl:port name="LocalhostTestWebservicePort" binding="tns:LocalhostTestWebserviceBinding">
<soap:address location="http://localhost/api/soap/test/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
You can fix this by enabling SOAP_SINGLE_ELEMENT_ARRAYS
on your SoapServer: 您可以通过在
SOAP_SINGLE_ELEMENT_ARRAYS
上启用SOAP_SINGLE_ELEMENT_ARRAYS
来解决此问题:
$server = new SoapServer('wsdl.xml', [
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
]);
I didn't test this solution, but you can check: 我没有测试此解决方案,但是您可以检查:
In your message part: 在您的消息部分:
<message name="getItemsResponse">
<part name="items" type="ns:ArrayOfItems"/>
</message>
Types part: 键入部分:
<xsd:schema targetNamespace="http://foo.bar/objectsoapserver/types"
xmlns="http://foo.bar/objectsoapserver/types">
<xsd:complexType name="ArrayOfItems">
<xsd:complexContent>
<xsd:restriction base="soapenc:Array">
<xsd:attribute ref="soapenc:arrayType" soap:arrayType="ns:Items[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="id" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Items" nillable="true" type="ns:Items"/>
</xsd:schema>
BTW. BTW。 Why don't you use the library to generate WSDL automatically?
为什么不使用该库自动生成WSDL?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.