我有一个关于PHP中的SOAP调用的问题。有一个名为“DoBulkOperation”的Web服务,它接收任何内容列表,执行某些操作,并返回一个列表,其中包含有关它所执行操作的信息。这里重要的是,请求的每个列表元素在同一索引的响应中都有其对应部分。
我得到的回应是这样的:
<Body>
<DoBulkOperationResponse>
<items>
<OperationResponse>
<result>17</result>
</OperationResponse>
<Error>Some error occured</Error>
<OperationResponse>
<result>18</result>
</OperationResponse>
<OperationResponse>
<result>19</result>
</OperationResponse>
<OperationResponse>
<result>20</result>
</OperationResponse>
</items>
</DoBulkOperationResponse>
</Body>
对我的请求的正确回应。现在,我可以说,请求中的第二个列表元素有问题。
我从PHP SoapClient获得的不是我所期望的:
object(stdClass)#49 (1) {
["items"]=>
object(stdClass)#51 (2) {
["OperationResponse"]=>
array(4) {
[0]=>
object(stdClass)#53 (1) {
["customerID"]=>
int(17)
}
[1]=>
object(stdClass)#52 (1) {
["customerID"]=>
int(18)
}
[2]=>
object(stdClass)#50 (1) {
["customerID"]=>
int(19)
}
[3]=>
object(stdClass)#54 (1) {
["customerID"]=>
int(20)
}
}
["Error"]=>
string(17) "Some error occured"
}
}
元素的顺序完全被破坏了。现在,无法确定哪个请求元素会导致哪个响应元素。
在WSDL中,“items”被定义为序列。
有没有办法强制SoapClient实例保留响应的结构?
致以最诚挚的问候,
马库斯
答案 0 :(得分:5)
这里有几个选项,但是为了得到明确的答案,你应该为这个电话提供WSDL。
设置或添加array('features' => SOAP_SINGLE_ELEMENT_ARRAYS)
作为SoapClient的选项。只有遇到多个元素时,它才会阻止结果产生数组。从我认为PHP做的内部:在第一次元素遭遇,它刚刚创建,并在下次遇到时,第一个元素被移动到一个数组,第二个元素然后被添加。
这可能已经解释了您所看到的结构,并且可能能够解决它。
您必须在WSDL中找到ComplexType结构的名称,然后可以创建用于这些而不是stdClass
的PHP类。这对所有内容都非常有用,因为您的IDE可以为您提供自动完成功能,您可以使用get_class()
实际查看您正在处理的元素。另一方面,您无法创建一个正确充当XML中items
结构的PHP对象,因此这可能只是装饰性的,但它是必要的......
__set()
来干扰创建结果。您可以创建一个用作items
的自定义类,它将设置所有属性。在魔术功能中,您可以尝试推送数据。至少你可以用一些输出来调试它。
在选项数组中设置选项trace => true
,然后使用SoapClient::__getLastResponse
。
PHP可能无法将您获得的XML结构转换为正确的结果。我会责怪你提供的Soap API。通常会提供将某种ID附加到请求并在结果上重用此ID以使客户端能够识别其内容。至少“按请求顺序”返回的结构应始终返回相同的项目,并将结果传递到内部,如:
<OperationResponse>
<result>17</result>
</OperationResponse>
<OperationResponse>
<Error>Some error occured</Error>
</OperationResponse>