2

我有一个关于 PHP 中的 SOAP 调用的问题。有一个名为“DoBulkOperation”的网络服务,它接受一个列表,做某事,并返回一个列表,其中包含关于它所做的事情的信息。这里重要的是,请求的每个列表元素在响应中具有相同索引处的对应项。

我得到的回应是这样的:

<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 中,“项目”被定义为序列。

有没有办法强制 SoapClient 实例保留响应的结构?

此致,

马库斯

4

1 回答 1

5

您在这里有几个选项,但要获得明确的答案,您应该为此调用提供 WSDL。

强制 PHP SoapClient 始终返回定义的数组。

设置或添加array('features' => SOAP_SINGLE_ELEMENT_ARRAYS)为 SoapClient 的选项。只有在遇到多个元素时,它才会阻止结果包含数组。从我相信 PHP 的内部操作来看:在第一次遇到元素时,它刚刚被创建,而在下一次遇到时,第一个元素被移动到一个数组中,然后第二个元素被添加。

这可能已经解释了您所看到的结构,并且可能能够修复它。

将类映射与预定义预期结构的对象一起使用。

您必须在 WSDL 中找出 ComplexType 结构的名称,然后才能创建用于这些结构的 PHP 类,而不是stdClass. 这对任何事情都非常有用,因为您的 IDE 可以为您提供自动完成功能,并且您实际上可以通过使用它来查看正在处理的元素get_class()。另一方面,您无法创建正确充当itemsXML 结构的 PHP 对象,因此这可能只是装饰性的,但对于...

在您的自定义类中使用魔法__set()来干扰创建结果。

您也许可以创建一个自定义类,用作items设置所有属性的类。在魔术函数中,您可以尝试推送数据。至少你可以用一些输出来调试它。

跟踪请求并直接访问 XML 结果。

trace => true在选项数组中设置选项,并使用SoapClient::__getLastResponse.

为失败做好准备。

PHP 可能只是无法将您获得的 XML 结构转换为正确的结果。我会责怪您提供的 Soap API。人们通常会提供在请求中附加某种 ID 并在结果中重用此 ID 以使客户能够识别他们的东西。至少“按请求顺序”返回的结构应该始终返回相同的项目并将结果携带到内部某处,例如:

<OperationResponse>
    <result>17</result>
</OperationResponse>
<OperationResponse>
    <Error>Some error occured</Error>
</OperationResponse>
于 2013-04-06T18:24:34.783 回答