php SOAP之多层complex类型

来源:互联网 发布:linux查看目录 编辑:程序博客网 时间:2024/06/06 00:42

从NuSoap到php Soap,真是付出了惨痛的代价。
php Soap对于complex 参数类型的封装,采用array来实现,array扮演了class的角色;
如果在WSDL文件中定义了以下complex参数

<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions name="XXXX" targetNamespace="http://www.example.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.com"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <wsdl:types>    <xsd:schema targetNamespace="http://www.example.com">        <xsd:complexType name="BusinessErrorType">        <xsd:sequence>            <xsd:element name="severityCode" type="xsd:string" minOccurs="0">            </xsd:element>            <xsd:element name="reasonCode" type="xsd:string" minOccurs="0">            </xsd:element>            <xsd:element name="reasonText" type="xsd:string" minOccurs="0">            </xsd:element>            <xsd:element name="reasonDetail" type="xsd:string" minOccurs="0">            </xsd:element>        </xsd:sequence>    </xsd:complexType>      <xsd:element name="AddAccessCardDetails" type="tns:AccessCardRequestType">      </xsd:element>      <xsd:element name="AddAccessCardDetailsResponse">        <xsd:complexType>          <xsd:sequence>            <xsd:element name="messageId" type="xsd:string">            </xsd:element>            <xsd:element name="resultCondition" type="tns:BusinessErrorType" />          </xsd:sequence>        </xsd:complexType>      </xsd:element>            <xsd:complexType name="AccessCardRequestType">                <xsd:sequence>                    <xsd:element name="messageId" type="xsd:string"></xsd:element>                    <xsd:element maxOccurs="unbounded" minOccurs="1" name="cardInfo" type="tns:CardLocationAccessInfoType">                    </xsd:element>                </xsd:sequence>            </xsd:complexType>            <xsd:complexType name="CardLocationAccessInfoType">              <xsd:sequence>                    <xsd:element minOccurs="0" name="residentID" type="xsd:string">                    </xsd:element>                    <xsd:element name="cardUID" type="tns:CardUIDType">                    </xsd:element>                    <xsd:element name="accessExpiryDate" type="xsd:string">                    </xsd:element>                    <xsd:element minOccurs="0" name="locationAccess" type="tns:LocationAccessType" maxOccurs="unbounded">                    </xsd:element>                </xsd:sequence>            </xsd:complexType>            <xsd:complexType name="LocationAccessType">                <xsd:sequence>                    <xsd:element name="accessPermission">                        <xsd:simpleType>                            <xsd:restriction base="xsd:string">                                <xsd:enumeration value="ALLOW"></xsd:enumeration>                                <xsd:enumeration value="BLOCK"></xsd:enumeration>                            </xsd:restriction>                        </xsd:simpleType>                    </xsd:element>                    <xsd:element name="project" type="xsd:string">                    </xsd:element>                    <xsd:element name="building" type="xsd:string">                    </xsd:element>                    <xsd:element minOccurs="0" name="wing"                        type="xsd:string" />                    <xsd:element name="door" type="xsd:string"></xsd:element>                </xsd:sequence>            </xsd:complexType>            <xsd:complexType name="CardUIDType">                <xsd:sequence>                    <xsd:element name="ARN" type="xsd:string"></xsd:element>                    <xsd:element name="expiryDate" type="xsd:string"></xsd:element>                </xsd:sequence>            </xsd:complexType>    </xsd:schema>  </wsdl:types>  <wsdl:message name="AddAccessCardDetailsRequest">    <wsdl:part element="tns:AddAccessCardDetails" name="parameters"/>  </wsdl:message>  <wsdl:message name="AddAccessCardDetailsResponse">    <wsdl:part element="tns:AddAccessCardDetailsResponse" name="parameters"/>  </wsdl:message>  <wsdl:portType name="XPServices">    <wsdl:operation name="AddAccessCardDetails">      <wsdl:input message="tns:AddAccessCardDetailsRequest"/>      <wsdl:output message="tns:AddAccessCardDetailsResponse"/>    </wsdl:operation>  </wsdl:portType>  <wsdl:binding name="XServicesSOAP"    type="tns:XPServices">    <soap:binding style="document"        transport="http://schemas.xmlsoap.org/soap/http" />    <wsdl:operation name="AddAccessCardDetails">        <soap:operation            soapAction="AddAccessCardDetails" />        <wsdl:input>            <soap:body use="literal" />        </wsdl:input>        <wsdl:output>            <soap:body use="literal" />        </wsdl:output>    </wsdl:operation>  </wsdl:binding>  <wsdl:service name="XServices">    <wsdl:port name="XServicesSOAP" binding="tns:XServicesSOAP">        <soap:address location='http://www.example.com/Xservice.php'/>    </wsdl:port>  </wsdl:service></wsdl:definitions>

则在调用接口AddAccessCardDetails时应该这样传参:

<?php$client = new SoapClient("http://www.example.com/Xservice.php?WSDL", array('trace'=>true));$cardUID = array('ARN'=>'100000000000002', 'expiryDate'=>2044);$locationAccess10 = array(    'accessPermission'=>'ALLOW',    'project'=>'CASA BELLA',     'building'=>'MAGNIFICA',    'wing'=>'C',    'door'=>'301'    );$locationAccess11 = array(    'accessPermission'=>'ALLOW',    'project'=>'CASA BELLA',     'building'=>'MAGNIFICA',    'wing'=>'E',    'door'=>'302'    );$locationAccessS = array($locationAccess10, $locationAccess11);$cardInfo1 = array(    'residentID'=>'1000010',    'cardUID'=>$cardUID,    'accessExpiryDate'=>'24/03/2016',    'locationAccess'=>$locationAccessS    );$cardUID2 = array('ARN'=>'000000011479FFFFFFFFFFFFFFFFFF', 'expiryDate'=>2044);$locationAccess20 = array(    'accessPermission'=>'ALLOW',    'project'=>'CASA BELLA',    'building'=>'MAGNIFICA',    'wing'=>'C',    'door'=>'302'    );$locationAccessS2 = array($locationAccess20);$cardInfo2 = array(    'residentID'=>'1000011',    'cardUID'=>$cardUID2,    'accessExpiryDate'=>'24/03/2016',    'locationAccess'=>$locationAccess20    );$cardUID3 = array('ARN'=>'100000000000004', 'expiryDate'=>2045);$cardInfo3 = array(    'residentID'=>'1000013',    'cardUID'=>$cardUID3,    'accessExpiryDate'=>'24/03/2016',    );$cardInfo = array($cardInfo1,$cardInfo2,$cardInfo3);try {    $response = $client->AddAccessCardDetails(array('messageId'=>rand(), 'cardInfo'=>$cardInfo));    print_r($response);  }catch (SoapFault $e){    echo '<h2>Debug</h2>';    echo $e->getMessage();}echo '<h2>Request</h2>';echo '<pre>'.htmlspecialchars($client->__getLastRequest(), ENT_QUOTES).'</pre>';echo '<h2>Response</h2>';echo '</pre>'.htmlspecialchars($client->__getLastResponse(), ENT_QUOTES).'</pre>';?> 

而服务器在处理参数时,应该将参数作为一个对象来处理,伪代码如下

function AddAccessCardDetails($msg){    $messageId = $msg->messageId;    /*这里$msg->cardInfo可能是一个数组也可能是单独一个元素,取决于客户端传递了一个还是多个cardInfo,详细见WSDL文件*/    $cardInfos = $msg->cardInfo;    if(!is_array($cardInfos)){        $cardInfos = array($cardInfos);    //not a array, we make it a array    }    foreach ($cardInfos as $cardInfo){        $resident = $cardInfo->residentID;        $accessExpiryDate = $cardInfo->accessExpiryDate;        $cardUID = $cardInfo->cardUID;        $locationAccessS = $cardInfo->locationAccess;        $ARN = $cardUID->ARN;        $expiryDate = $cardUID->expiryDate;        ---------------处理数据---------------------    }}
0 0
原创粉丝点击