如何使用PHP在SOAP响应中包含多个相同类型的对象


How to include multiple objects of the same type in SOAP Response using PHP

我使用的是PHP的SoapServer,我希望响应包含多个相同类型的项。本节的wsdl如下所示。

<xsd:element name="getSalesTaxResponse">
    <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="totalTaxAmount" type="xsd:string"></xsd:element>
            <xsd:element maxOccurs="unbounded" minOccurs="1" name="productTax" type="tns:getSalesTaxResultInformation" />
          </xsd:sequence>
    </xsd:complexType>
</xsd:element>
<xsd:complexType name="getSalesTaxResultInformation">
    <xsd:annotation>
        <xsd:documentation>This object stores information related to product tax request
        </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element name="productId" type="xsd:string"></xsd:element>
        <xsd:element name="productNRCPrice" type="xsd:string"></xsd:element>
        <xsd:element name="taxAmount" type="xsd:string"></xsd:element>
    </xsd:sequence>
</xsd:complexType>

在PHP中,我的大脑被卡住了,我一辈子都想不出如何在响应中包含多个"productTax"记录。我目前正在做这件事,但它并没有达到我想要的效果。

        $this->response = new GetSalesTaxResponse();
        $this->response->totalTaxAmount = '21.93';
        $this->response->productTax = array(
            (object) array(
                'productId'=>'3123',
                'productNRCPrice'=>'201.20',
                'taxAmount'=>'10.10'),
            (object) array('productId'=>'2103',
                'productNRCPrice'=>'102.10',
                'taxAmount'=>'11.83')
        );
        file_put_contents('/tmp/burp', print_r($this->response, TRUE), FILE_APPEND);
        return $this->response->getSoapVar();

但在SOAP-UI中,我看到了这一点。

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://www.example.com/SOAP/Billing">
   <SOAP-ENV:Body>
      <ns1:getSalesTaxResponse>
         <totalTaxAmount>21.93</totalTaxAmount>
         <productTax>
            <SOAP-ENC:Struct>
               <productId>3123</productId>
               <productNRCPrice>201.20</productNRCPrice>
               <taxAmount>10.10</taxAmount>
            </SOAP-ENC:Struct>
            <SOAP-ENC:Struct>
               <productId>2103</productId>
               <productNRCPrice>102.10</productNRCPrice>
               <taxAmount>11.83</taxAmount>
            </SOAP-ENC:Struct>
         </productTax>
      </ns1:getSalesTaxResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

基于我在PHP中所做的工作,这是有道理的,但我如何在PHP中构建响应,使其看起来像这样呢

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://www.example.com/SOAP/Billing">
       <SOAP-ENV:Body>
          <ns1:getSalesTaxResponse>
             <totalTaxAmount>21.93</totalTaxAmount>
             <productTax>
                   <productId>3123</productId>
                   <productNRCPrice>201.20</productNRCPrice>
                   <taxAmount>10.10</taxAmount>
              </productTax>
              <productTax>
                   <productId>2103</productId>
                   <productNRCPrice>102.10</productNRCPrice>
                   <taxAmount>11.83</taxAmount>
             </productTax>
          </ns1:getSalesTaxResponse>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

要从PHP中设置复杂类型数组,必须创建一个新的复杂类型,getSalesTaxResponse使用该类型,并具有数组类型为getSalesTaxResultInformation:的元素序列

<complexType name="getSalesTaxResultInformation_Array">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <sequence>
        <element name="productTax" type="tns:getSalesTaxResultInformation"
                 maxOccurs="unbounded"/>
      </sequence>
    </restriction>
  </complexContent>
</complexType>

这使得您的getSalesTaxResponse如下:

<xsd:element name="getSalesTaxResponse">
    <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="totalTaxAmount" type="xsd:string"></xsd:element>
            <xsd:element maxOccurs="unbounded" minOccurs="1" name="productTax" type="tns:getSalesTaxResultInformation_Array" />
          </xsd:sequence>
    </xsd:complexType>
</xsd:element>

这为SoapServer提供了足够的信息来计算数组数据的类型,本质上是一个映射

如果SoapServer找不到合适的数组元素类型,则必须自己将每个productTax行强制转换为getSalesTaxResultInformation

$array_element = new SoapVar($response_array, SOAP_ENC_OBJECT, null, null, 'getSalesTaxResultInformation');