Soap php强制将序列转换为php数组

时间:2016-10-24 14:07:37

标签: php arrays xml soap

我正在使用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值的方式的参考文档?

2 个答案:

答案 0 :(得分:3)

解决方案是在创建SOAP_SINGLE_ELEMENT_ARRAYS时启用SoapClient功能:

$client = new SoapClient($wsdl, array(
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
));

答案 1 :(得分:0)

我强烈建议你使用WSDL到php生成器,这样你总会得到你想要的类型的PHP对象,或者如果你应该得到一个数组,那么最后得到一个数组。您应该尝试PackageGenerator项目。