3

I'm relatively new to Soap on the "creating the service side", so appologies in advance for any terminology I'm munging.

Is it possible to return a PHP array from a Remote Procedure Soap Service that's been setup using PHP's SoapServer Class?

I have a WSDL (built by blindly following a tutorial) that, in part, looks something like this

<message name='genericString'>
    <part name='Result' type='xsd:string'/>
</message>

<message name='genericObject'>
    <part name='Result' type='xsd:object'/>
</message>

<portType name='FtaPortType'>       
    <operation name='query'>
        <input message='tns:genericString'/>
        <output message='tns:genericObject'/>
    </operation>        
</portType>

The PHP method I'm calling is named query, and looks something like this

public function query($arg){
    $object = new stdClass();
    $object->testing = $arg;
    return $object;     
}

This allows me to call

$client = new SoapClient("http://example.com/my.wsdl");
$result = $client->query('This is a test');

and dump of result will look something like

object(stdClass)[2]
    public 'result' => string 'This is a test' (length=18)

I want to return a native PHP array/collection from my query method. If I change my query method to return an array

public function query($arg) {
    $object = array('test','again');
    return $object;
}

It's serialized into an object on the client side.

object(stdClass)[2]
    public 'item' => 
        array
            0 => string 'test' (length=4)
            1 => string 'again' (length=5)

This makes sense, as I've specific a xsd:object as the Result type in my WSDL. I'd like to, if possible, return an native PHP array that's not wrapped in an Object. My instincts say there's a specific xsd:type that will let me accomplish this, but I don't know. I'd also settle for the object being serialized as an ArrayObject.

Don't hold back on schooling me in the technical details os WSDL. I'm trying to get a grasp on the underlying concepts fo

Alana Storm
  • 164,128
  • 91
  • 395
  • 599

3 Answers3

7

Little trick - encode as JSON objects, decode back into recursive associative arrays:

$data = json_decode(json_encode($data), true);
lubosdz
  • 4,210
  • 2
  • 29
  • 43
3

I used this WSDL generator to create description file.

Returning array of strings is something what my web service does, here's part of WSDL:

<wsdl:types>
<xsd:schema targetNamespace="http://schema.example.com">
  <xsd:complexType name="stringArray">
    <xsd:complexContent>
      <xsd:restriction base="SOAP-ENC:Array">
        <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]" />
      </xsd:restriction>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

</wsdl:types>
<message name="notifyRequest">
  <part name="parameters" type="xsd:string" />
</message>
<message name="notifyResponse">
  <part name="notifyReturn" type="tns:stringArray" />
</message>

Then API function notify is defined:

<wsdl:operation name="notify">
  <wsdl:input message="tns:notifyRequest" />
  <wsdl:output message="tns:notifyResponse" />
</wsdl:operation>
Michał Niedźwiedzki
  • 12,859
  • 7
  • 45
  • 47
0

Alan, why not cast your object as an array when your client receives the response?

e.g.

(array) $object;

This will convert your stdClass object into an array, there is no measurable overhead to this, and is O(1) in PHP.

You may want to try changing the type from xsd:object to soap-enc:Array as well.

hobodave
  • 28,925
  • 4
  • 72
  • 77
  • 2
    Two reasons. Because that would give me an array with a single key named "item" that contained my array, and more importantly, I want to create a service that end users can use and get an array back from without having to cast it. – Alana Storm Jul 24 '09 at 17:04
  • And soap-enc:Array doesn't suit your needs? – hobodave Jul 24 '09 at 20:48
  • 3
    Keep in mind though, that this doesn't convert recursively. So if you have stdClass object's in deeper levels of your response they won't be converted. In this case the only way I can think of is lubosdz's answer. – flu Sep 02 '15 at 10:41