【发布时间】:2016-10-24 14:07:36
【问题描述】:
我正在用 php 测试一些 Soap 功能
$soapClient = new CustomSoapClient($urlWsdl,[
'exceptions' => true
'trace' => true,
'location' => $soapUrl
]);
$soapResponse = $soapClient->__call('ProfileLookup',$methodArgs)
CustomSoapClient 是一个扩展基础 SoapClient 类的类,用于记录 xml 请求和响应(在“__doRequest”方法中。 $soapUrl 是一个测试 Soap 服务器的位置,它能够通过返回一个或多个结果来响应 ProfileLookup 方法
wsdl ($urlWsdl) 定义了这个方法和它的返回类型
<wsdl:operation name="ProfileLookup">
<wsdl:input message="tns:ProfileLookupRequest"/>
<wsdl:output message="tns:ProfileLookupResponse"/>
</wsdl:operation>
<wsdl:message name="ProfileLookupResponse">
<wsdl:part name="LookupResponse" element="n:LookupResponse"/>
</wsdl:message>
<xs:element name="LookupResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="Result" type="c:ResultStatus"/>
<xs:element name="ProfileLookups" type="tns:ProfileLookupList"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="ProfileLookup">
<xs:sequence>
<xs:element name="PersonName" type="c:PersonName"/>
...
</xs:sequence>
</xs:complexType>
<xs:complexType name="ProfileLookupList">
<xs:sequence>
<xs:element name="ProfileLookup" type="tns:ProfileLookup" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
如果我调用我的 Web 服务并且该服务返回多个结果,则返回的 xml 正常
<env:Body>
<ns1:LookupResponse>
<ns1:Result resultStatusFlag="SUCCESS"/>
<ns1:ProfileLookups>
<ns1:ProfileLookup>
<ns1:PersonName>
</ns1:PersonName>
</ns1:ProfileLookup>
<ns1:ProfileLookup>
<ns1:PersonName>
</ns1:PersonName>
</ns1:ProfileLookup>
</ns1:ProfileLookups>
</ns1:LookupResponse>
</env:Body>
这就是这个响应在 php 中的转换方式
[ProfileLookups] => stdClass Object (
[ProfileLookup] => Array(
[0] => stdClass Object (
[PersonName] => stdClass Object()
),
[1] => stdClass Object (
[PersonName] => stdClass Object()
)
)
)
如果我为了只得到一个结果而调用 Web 服务,我会得到相同的 xml 结构
<env:Body>
<ns1:LookupResponse>
<ns1:Result resultStatusFlag="SUCCESS"/>
<ns1:ProfileLookups>
<ns1:ProfileLookup>
<ns1:PersonName>
</ns1:PersonName>
</ns1:ProfileLookup>
</ns1:ProfileLookups>
</ns1:LookupResponse>
</env:Body>
但是转换成php值不同:
[ProfileLookups] => stdClass Object (
[ProfileLookup] => stdClass Object(
[PersonName] => stdClass Object()
)
)
如您所见,在第一个示例中,ProfileLookup 是“ProfileLookup”类型的对象数组,而在第二个示例中,ProfileLookup 本身就是“ProfileLookup”类型的对象。
所以如果只返回一项,下面的代码会导致错误。
foreach($soapResponse->ProfileLookups->ProfileLookup as $profileLookup){
echo $profileLookup->PersonName->...
}
当然,我可以轻松测试 ProfileLookups->ProfileLookup 是数组还是对象,然后强制它成为数组。但这似乎不是正确的方法,因为我在应用程序的每个部分都可能遇到这个问题。
控制 SoapClient 将 xml 转换为 php 值的方式的解决方案是什么? 自己解析 xml 响应会更好吗? 像 Zend\Soap 这样的库可以在这个用例中提供帮助吗? 我在哪里可以找到有关 SoapClient 将 xml 转换为 php 值的参考文档?
【问题讨论】: