I'm working on the following what I hope would be a simple script. I'm using the Cisco AXL WSDL to reach out to my Cisco CUPS server run a SQL query, loop through the results and then feed that back into another step to update the returned rows to a certain value. However I'm having a challenge when the SOAP response I get back differs from either being a single row (array object) versus multiple rows (arrays within arrays).
Here's the script right now I'm just trying to loop through and echo out what I'm getting before going more complex.
<?php
$client = new SoapClient("/var/www/AXLAPI.wsdl",
array('trace'=>true,
'exceptions'=>true,
'location'=>"https://cups-test:8443/axl",
'login'=>'admin',
'password'=>'password',
));
$response = $client->executeSQLQuery(array("sql"=>"select pkid from epasenduser where enablemoc = 't'"));
// var_dump($response);
foreach ($response as $row){
// var_dump($row->row);
echo("PKID: ".$row->pkid)."<br>";
}
?>
Lets start with showing what the actual SOAP response is: For a single Row it looks like this:
object(stdClass)#2 (1) {
["return"]=>
object(stdClass)#3 (1) {
["row"]=>`
object(stdClass)#4 (1) {
["pkid"]=>
string(36) "9dbd9b32-8d64-41ad-a355-8f62e050ffce"
}
}
}
And for multiple rows:
object(stdClass)#2 (1) {
["return"]=>
object(stdClass)#3 (1) {
["row"]=>
array(2) {
[0]=>
object(stdClass)#4 (1) {
["pkid"]=>
string(36) "fa0540f7-8e75-481b-a193-7a06d7f601a8"
}
[1]=>
object(stdClass)#5 (1) {
["pkid"]=>
string(36) "fa0c8c7a-79be-4667-ae70-c3e773908b52"
}
}
}
}
The challenge here is since the object returns multiple times in the SOAP response I'm guessing PHP is assigning an integer value incrementing each time it sees it. So If i want to get to the point where where I can just reference PKID I end up with two different statements:
For a single item it is:
foreach ($response->return as $row){
var_dump($row->pkid);
}
And for multiple items it is:
foreach ($response->return->row as $row){
var_dump($row->pkid);
}
So the question is, is there a way for me to accomplish returning just the PKID values in my foreach loop without having the evaluate the array ahead of time? Hopefully this makes sense, self admitted network engineer first and infantile "developer" second.
All comes down to making php less smart and ensuring I always get an array back.
Wonderful write up about it here: http://blog.jasonrichardsmith.org/programming/soap-and-single-element-arrays/
Long and short of it was to change my connection setup:
$client = new SoapClient("/var/www/AXLAPI.wsdl",
array('trace'=>true,
'exceptions'=>true,
'features'=>SOAP_SINGLE_ELEMENT_ARRAYS,
'location'=>"https://cups-test:8443/axl",
'login'=>'admin',
'password'=>'password',
));
Including the 'features'=>SOAP_SINGLE_ELEMENT_ARRAYS,
command ensures even on single results it's built as an array not an object.