php SOAP之多层complex类型

从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;

        ---------------处理数据---------------------
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值