我正在使用php测试一些Soap功能
$soapClient = new CustomSoapClient($urlWsdl,[
'exceptions' => true
'trace' => true,
'location' => $soapUrl
]);
$soapResponse = $soapClient->__call('ProfileLookup',$methodArgs)
CustomSoapClient是一个扩展基本SoapClient类的类,用于记录xml请求和响应(在" __ doRequest"方法中)。 $ soapUrl是测试Soap Server的位置,它能够通过返回一个或多个结果来回答方法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是OK
<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是一个类型为&#34; ProfileLookup&#34;的对象数组,在第二个中,ProfileLookup本身就是一个类型&#34; ProfileLookup&#34;的对象。
因此,如果只返回一个项目,以下代码将导致错误。
foreach($soapResponse->ProfileLookups->ProfileLookup as $profileLookup){
echo $profileLookup->PersonName->...
}
当然,我可以轻松测试ProfileLookups-&gt; ProfileLookup是一个数组还是一个对象然后强制它成为一个数组。但这似乎并不是正确的方法,因为我可以在应用程序的每个部分遇到这个问题。
控制SoapClient将xml转换为php值的方式可能是什么? 自己解析xml响应会更好吗? 像Zend \ Soap这样的库可以帮助这个用例吗? 我在哪里可以找到关于SoapClient将xml转换为php值的方式的参考文档?
答案 0 :(得分:3)
解决方案是在创建SOAP_SINGLE_ELEMENT_ARRAYS
时启用SoapClient
功能:
$client = new SoapClient($wsdl, array(
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
));
答案 1 :(得分:0)
我强烈建议你使用WSDL到php生成器,这样你总会得到你想要的类型的PHP对象,或者如果你应该得到一个数组,那么最后得到一个数组。您应该尝试PackageGenerator项目。