Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP SoapClient type mapping behaves differently

I've a web-service function which is returning an array of items to a PHP-Client. Depending on the number of items, the PHP return type is differently. If the function returns one item the PHP type is stdClass if the function returns more than one item, the PHP type is array. In either case it should be array. What can I do to achieve this?

Details:

A var_dump of the result from the web-service function looks like following:
  • if one item is in the result:
    array(3) { ["filterErg"]=> object(stdClass)#37 (1) { ["item"]=> object(stdClass)#38 (9) ...
  • if more than one item is in the result:
    array(3) { ["filterErg"]=> object(stdClass)#37 (1) { ["item"]=> array(16) ...

The name of the function is getFilter and the relevant parts of the WSDL File are:

<types>
  <schema ...>
    <complexType name="arrayFilter">
      <sequence>
        <element name="item" type="ns1:stFilter" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
      </sequence>
    </complexType>
    ...
  </schema>
</types>

<message name="getFilterResponse">
  <part name="filterErg" type="ns1:arrayFilter"/>
  <part name="functionResult" type="xsd:int"/>
  <part name="outErr" type="xsd:string"/>
</message>

<portType name="ADServicePortType">    
  <operation name="getFilter">
    <documentation>Service definition of function ns1__getFilter</documentation>
    <input message="tns:getFilter"/>
    <output message="tns:getFilterResponse"/>
  </operation>
  ...
</portType>

<binding name="ADService" type="tns:ADServicePortType">
  <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="getFilter">
    <SOAP:operation style="rpc" soapAction=""/>
    <input>
      <SOAP:body use="encoded" namespace="urn:ADService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    </input>
    <output>
      <SOAP:body use="encoded" namespace="urn:ADService" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    </output>
  </operation>
  ...
</binding>
like image 387
Christian Ammer Avatar asked Jun 20 '11 07:06

Christian Ammer


People also ask

How does the soapclient work with the classmap?

After configuring the classmap, whenever you perform a certain operation that returns a type Address or Book, the SoapClient will instantiate that class, fill the fields with the data and return it from the operation call.

How to call the requestinfo SOAP method from the soapclient class?

The SoapClient class is equipped with a __call method. This is not to be called directly. Instead this allows you to do: This will call the requestInfo SOAP method. Table of possible $options values ( Array of key/value pairs ): URL of SOAP server. Required in non-WSDL mode. Can be used in WSDL mode to override the URL.

What are the possible values of soap_SSL_method_TLS in PHP?

Possible values are SOAP_SSL_METHOD_TLS, SOAP_SSL_METHOD_SSLv2, SOAP_SSL_METHOD_SSLv3 or SOAP_SSL_METHOD_SSLv23. Issue with 32 bit PHP: In 32 bit PHP, numeric strings greater than 32 bits which are automatically cast to integer by xs:long will result in it hitting the 32 bit limit, casting it to 2147483647.

How do I map WSDL types to PHP classes?

The classmap option can be used to map some WSDL types to PHP classes. This option must be an array with WSDL types as keys and names of PHP classes as values.


2 Answers

You can use SOAP_SINGLE_ELEMENT_ARRAYS option when you are creating SoapClient

$soapConfig = array(
    'soap_version' => SOAP_1_2,
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
    'trace'    => true
);
$client = new SoapClient('http://localhost:8070/Services.wsdl', $soapConfig);
like image 151
hakan Avatar answered Sep 20 '22 13:09

hakan


Change the variable from object to an array containing the object on occasion:

if (is_object($variable))
{
    $variable = array($variable);
}

Or more specifically in your case:

if (is_object($result["filterErg"]->item))
{
    $result["filterErg"]->item = array($result["filterErg"]->item);
}
like image 21
hakre Avatar answered Sep 19 '22 13:09

hakre