GarrettBartley.com

Structs, Arrays, and Arrays of Structs in WSDL

I’ve been getting into creating web services lately for all sorts of tasks. I started out with XML-RPC and was hammering away pretty well with it until I discovered that .Net didn’t like to play with XML-RPC. Since this was for a top-priority project at work, I dove head first into SOAP despite not wanting to have to deal with WSDLs. It seemed that I was in luck. Built-in SOAP support for PHP 5.x seemed to have finally matured and I didn’t have to rely on sparsely-documented libraries. Once I got the hang of writing a WSDL (basically, I found a good template), I was well on my way. The great thing about SOAP and WSDLs are that the server and client both automatically seem to handle a lot of error-checking for you. For a high priority action item with just a couple of hours to complete it and diving into something I knew little about, this worked out very well.

I chugged along at my various projects and web services until I hit a roadblock. I wanted to return a multi-dimensional array from PHP. That’s when it all came to a screeching halt. I could not find ANY documentation on this no matter how many different ways I tried to search using Google. Heck, I even tried Bing! No luck at all. So, I decided to put it off for a few days just to give myself time to get over the frustration. Every time I started to try to think about it, I would feel the onset of a headache and just get irritable with myself. Headaches and irritations are terrible for programming!

After a few days, I decided that maybe what I needed was to learn a little bit about the basics of SOAP. Web sites seemed to just assume you knew what you were doing with SOAP and WSDLs from the get-go. I had a working web service with SOAP and a WSDL, but I didn’t have a clue what was going on (and, honestly, I still don’t have a concrete grasp on it all). However, it turns out that sometime several months ago, the company I work for bought an O’Reilly book on SOAP and it was collecting dust on my boss’s bookshelf. I immediately snagged it and started reading. A bunch of it was pretty basic but helped clarify some things. Then, there was about a page that roughly covered structs and arrays. It wasn’t much, but it was just enough. A struct is basically an associative array value (name = ‘Garrett’, age = 27). And an array is just a bunch of repeating values. So, what if I declared a struct complex type and then an array complex type that used the struct as the value. I tested returning arrays and structs individually and they both worked. Then I put them together…and they still worked! In essence, I have finally figured it out.

So, for your geeky pleasure, I have decided to document this experience and hope that Google indexes it for anyone else out there using PHP and SOAP to return the elusive multi-dimensional array. I won’t include the whole WSDL, but just the main message and types portions and the PHP functions used to return them.

(I apologize for the horizontal scrolling, but I like to keep my code tabbed and formatted nicely.)

<!-- The types declarations -->
<types>
	<schema xmlns="http://www.w3.org/2001/XMLSchema"
		targetNamespace="http://www.xmltc.com/railco/transform/schema/" >
 
		<!-- Here's the struct for name and age -->
		<complexType name="TestStruct">
			<sequence>
				<element name="name" type="xsd:string" />
				<element name="age" type="xsd:string" />
			</sequence>
		</complexType>
 
		<!-- Here's an array that just returns a series of simple string repeating values -->
		<complexType name="ArrayOfString">
			<complexContent>
				<restriction base="SOAP-ENC:Array">
					<sequence>
						<element name="test" type="string" minOccurs="0" maxOccurs="unbounded" nillable="true" />
					</sequence>
					<attributeGroup ref="SOAP-ENC:arrayType" xsd:arrayType="string[]" />
				</restriction>
			</complexContent>
		</complexType>
 
		<!-- Combine the two and we return an array of repeating structs! -->
		<complexType name="ArrayOfStruct">
			<complexContent>
				<restriction base="SOAP-ENC:Array">
					<sequence>
						<element name="test2" type="TestStruct" minOccurs="0" maxOccurs="unbounded" nillable="true" />
					</sequence>
					<attributeGroup ref="SOAP-ENC:arrayType" xsd:arrayType="TestStruct[]" />
				</restriction>
			</complexContent>
		</complexType>
 
	</schema>
</types>
 
<!-- And returning the ArrayOfStruct in a method -->
<message name="test_struct" />
<message name="test_struct_resp">
	<part name="test" type="xsd:ArrayOfStruct" />
</message>

Now, for the PHP.

# Return the array
function test_array() {
	return array('hi','there');
}
 
# Return the struct
function test_struct() {
	$arr = array(
		array(
			'name' => 'Garrett',
			'age' => 27
		),
		array(
			'name' => 'Amy',
			'age' => 28
		)
	);
 
	return $arr;
}

I didn’t include the code for returning the struct with a single entry, but I think you get the picture. Here’s what the response looks like in SOAP Client for the Mac (click image for larger version).
SOAP Client Struct Array

I really hope that helps someone out there because it frustrated me to no end for several days!

Also, if you do have a Mac, I HIGHLY recommend downloading SOAP Client. It is a very excellent piece of software that does one thing and does it very, very well!

Tags: , , , , , ,

One Response to Structs, Arrays, and Arrays of Structs in WSDL »»


Comments

  1. Pie
    Comment by Pie | 2009/07/27 at 21:50:45

    You have to figure out a crafty acronym for this using ROAP…Maybe Reciprocating
    ordered
    array for
    php or something along those lines.

    You know…soap on a roap


Leave a Reply »»

Spam protection by WP Captcha-Free