Array problems with X-Fire, SOAP and PHP

I’ve been working with X-fire / ageis services in SOAP now for a while, and there’s been only one issue I’ve not been able to solve. Arrays.

When the back-end send an array with item count > 1 everything works fine. The problems start when there is only one item in the array. The array is collapsed and instead there is a object that is the only item. At first I thought this was the java back-end that screwed up, but after inspecting the SOAP messages from NGREP I found out that it’s PHP that screws up.

I’ve prepared a short example called lookupPerson which takes a username and returns a Person with his related cars.

Consider the first sample, where the person has three cars:

SOAP request:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://api.service.com/temp/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="urn:Service">
<SOAP-ENV:Header>
<ns2:RemoteAddress xsi:type="SOAP-ENC:string">127.0.0.1</ns2:RemoteAddress>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:lookupPerson>
<ns1:in0>john</ns1:in0>
</ns1:lookupPerson>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

SOAP response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<lookupPersonResponse xmlns="http://api.service.com/temp/">
<out xmlns="http://api.service.com/temp/">
<username xmlns="http://users.model.service.com">john</username>
<cars xmlns="http://users.model.service.com">
<Car>
<car>HUMMER</car>
</Car>
<Car>
<car>BMW</car>
</Car>
</cars>
</out>
</lookupPersonResponse>
</soap:Body>
</soap:Envelope>

Now that looks pretty much right. Lets take a look at a var_dump of the returned object:

object(lookupPersonResponse)#571 (1) {
["out"]=> object(Person)#570 (2) {
["username"]=> string(11) "john"
["cars"]=> object(stdClass)#573 (1) {
["Car"]=> array(2) {
[0]=> object(Car)#572 (1) {
["car"]=> string(17) "BMW"
}
[1]=> object(Car)#574 (1) {
["car"]=> string(19) "HUMMER"
}
}
}
}
}

Yep. Everything is correct. The class map works as intended. Now, lets get over to the bad stuff. The following output is the same call, but this time John has lost his Hummer.

SOAP response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<lookupPersonResponse xmlns="http://api.service.com/temp/">
<out xmlns="http://api.service.com/temp/">
<username xmlns="http://users.model.service.com">john</username>
<cars xmlns="http://users.model.service.com">
<Car>
<car>BMW</car>
</Car>
</cars>
</out>
</lookupPersonResponse>
</soap:Body>
</soap:Envelope>

Well, the SOAP response is pretty much like the first one.

PHP object:

object(lookupPersonResponse)#571 (1) {
["out"]=> object(Person)#570 (2) {
["username"]=> string(11) "john"
["cars"]=> object(stdClass)#573 (1) {
["Car"]=> object(Car)#572 (1) {
["car"]=> string(17) "BMW"
}
}
}
}

Do you see the difference here? Car is pointing to the car object instance instead of an array. This lays the path for some ass logic work for everything that returns an array.

Lets take a look at the relevant parts of the WSDL:

<xsd:complexType name="Person">
<xsd:sequence>
<xsd:element minOccurs="0" name="username" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="cars" nillable="true" type="ns1:ArrayOfCar"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ArrayOfCar">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="Car" nillable="true" type="ns1:Car"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Car">
<xsd:sequence>
<xsd:element minOccurs="0" name="car" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="lookupPersonResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="ns1:Person"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

According to WSDL standard this is legal and should work, but I dont think PHP is too happy about it. I’ve tried doing similar stuff with a service that describes arrays as :


<complexType name="ArrayOf_soapenc_string">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="soapenc:string[]"/>
</restriction>
</complexContent>
</complexType>

This way seems to work just fine, so I fear that the problem has something to do with X-Fire and ageis. I’m very interested in some hints on how to get this running properly.

Advertisements

8 Comments

  1. Idetrorce said,

    December 15, 2007 at 2:23 pm

    very interesting, but I don’t agree with you
    Idetrorce

  2. eirikhoem said,

    December 16, 2007 at 12:49 pm

    Can you please elaborate a bit? šŸ™‚

  3. cmm said,

    February 21, 2008 at 12:35 pm

    We run into the same problem, and found the following:

    http://bugs.php.net/bug.php?id=36226

  4. March 13, 2008 at 8:14 am

    […] 13, 2008 at 8:14 am (PHP, SOAP, Tips) This is a followup to my post about array problems with SOAP and PHP. The scenario was that when an array with only one object was returned over SOAP the array was […]

  5. eirikhoem said,

    March 13, 2008 at 8:15 am

    Thanks cmm!

    I did a followup post – https://eirikhoem.wordpress.com/2008/03/13/array-problems-with-soap-and-php-updated/

  6. March 13, 2008 at 2:59 pm

    […] is a followup to my post about array problems with SOAP and PHP. The scenario was that when an array with only one object was returned over SOAP the array was […]

  7. March 17, 2008 at 2:02 pm

    […] pm (PHP, SOAP, Tips, X-Fire) This post is pretty much a revamp of a previous post called “Working with X-Fire soap services and inheritance in PHP“. That title was a bit misleading, and not really that good when it came to providing a […]

  8. March 17, 2008 at 5:46 pm

    […] post is pretty much a revamp of a previous post called “Working with X-Fire soap services and inheritance in PHP“. That title was a bit misleading, and not really that good when it came to providing a […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: