将对象数组从SOAP返回到PHP会产生额外的stdClass

时间:2014-08-19 14:04:10

标签: php arrays soap wsdl

虽然我发现了许多类似的话题,但我仍然无法解决我的问题。

我正在制作一个公共SOAP服务。它必须返回一个对象,其中一个值是一个对象数组(带有购买文章列表的电子商店订单)。

当我使用没有特殊设置的PHP SoapClient发出SOAP请求时,我收到一个订单,但它的文章被一个额外的stdClass包装:

object(stdClass)#3 (3) {
  ["order_id"] => string(1) "1"
  ["client_id"] => string(1) "1"
  ["articles"]=>
   object(stdClass)#2 (1) {    <-- I want to eliminate
    ["article"]=>              <-- these lines
    array(2) {
      [0]=>
      object(stdClass)#6 (2) {
        ["article_id"] => string(1) "2"
        ["quantity"] => string(1) "8"
      }
      [1]=>
      object(stdClass)#7 (2) {
        ["article_id"] => string(1) "4"
        ["quantity"]=> string(3) "1.5"
      }
    }
  }
}

原始对象是:

stdClass::__set_state(array(
   'order_id' => '1',
   'client_id' => 1,
   'articles' => 
      array (
        0 => 
        stdClass::__set_state(array(
           'article_id' => '2',
           'quantity' => 8,
        )),
        1 => 
        stdClass::__set_state(array(
           'article_id' => '4',
           'quantity' => 1.5,
        ))
      )
    )
)

WSDL是:

<wsdl:types>
    <xs:schema>
        <xs:element name="article">
            <xs:complexType>
                <xs:all>
                    <xs:element name="article_id" type="xs:int"></xs:element>
                    <xs:element name="quantity" type="xs:decimal"></xs:element>
                </xs:all>
            </xs:complexType>
        </xs:element>

        <xs:complexType name="articles">
            <xs:complexContent>
                <xs:restriction base="soapenc:Array">
                    <xs:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:article[]" />
                </xs:restriction>
            </xs:complexContent>
        </xs:complexType>

        <xs:element name="order">
            <xs:complexType>
                <xs:all>
                    <xs:element name="order_id" type="xs:int"></xs:element>
                    <xs:element name="client_id" type="xs:int"></xs:element>
                    <xs:element name="articles" type="articles"></xs:element>
                </xs:all>
            </xs:complexType>
        </xs:element>
    </xs:schema>
</wsdl:types>

<wsdl:message name="getOrderRequest">
    <wsdl:part name="id" type="xs:int" />
</wsdl:message>
<wsdl:message name="getOrderResponse">
    <wsdl:part name="order" element="tns:order" />
</wsdl:message>

<wsdl:portType name="orders">
    <wsdl:operation name="getOrder">
        <wsdl:input message="tns:getOrderRequest" />
        <wsdl:output message="tns:getOrderResponse" />
    </wsdl:operation>
</wsdl:portType>

SOAP响应是:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <SOAP-ENV:getOrderResponse>
            <order>
                <order_id>1</order_id>
                <client_id>1</client_id>
                <articles>
                    <article>
                        <article_id>2</article_id>
                        <quantity>8</quantity>
                    </article>
                    <article>
                        <article_id>4</article_id>
                        <quantity>1.5</quantity>
                    </article>
                </articles>
            </order>
        </SOAP-ENV:getOrderResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

虽然我可以正式制作类似$order->articles = $order->articles->article;的内容,但它并不好,因为它将是一个公共服务,我想为客户提供一个能够正确解析结果的代码示例。

在WSDL或PHP Soap客户端中应该更改哪些内容来解决此问题?

0 个答案:

没有答案