Reputation: 483
I'm trying to return an associative array in a PHP function. This function retrieves some data from MySQL and is published in a WebService using Zend Library.
This function looks like:
Functions.php
class Functions
{
/**
*
* @return array
*/
public function Function1()
{
$con = new mysqli(server, user, pass, database);
if ($con->connect_errno) {
die(__FUNCTION__ . $con->connect_error);
}
$con->set_charset('utf8');
$arrayRet = array();
$query = 'select field1, field2, field3 from table1';
if(!$result = $con->query($query)){
die(__FUNCTION__ . $con->error);
}
while( $row = $result->fetch_array(MYSQLI_ASSOC) )
$arrayRet[] = $row;
$result->close();
$con->close();
return $arrayRet;
}
}
Then I have another PHP file that lets me access the function via SOAP (using Zend Lib):
Server.php
<?php
include 'Zend/Soap/AutoDiscover.php';
include 'Zend/Soap/Server.php';
include 'Functions.php';
if(isset($_GET['wsdl']))
{
$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('Functions');
$autodiscover->handle();
}
else
{
$server = new Zend_Soap_Server("http://localhost/webservice/Server.php?wsdl");
$server->setClass('Functions');
$server->handle();
}
?>
So far everything looks quite normal. If i write a php client, i'm able to consume the webservice and access the returned array as follows:
<?php
$client = new Zend_Soap_Client('http://localhost/webservice/Server.php?wsdl');
$arrayRet = $client->Function1();
foreach($arrayRet as $row )
{
?>
<b>Field1: </b><?php echo $row['field1']; ?><br>
<b>Field2: </b><?php echo $row['field2']; ?><br>
<b>Field3: </b><?php echo $row['field3']; ?><br>
<?php
}
?>
Ok, now my problem is that i'm not writing a php client but a Android client. I'm using the ksoap2 library to achieve it. With this library i'm able to handle "normal arrays" with the pare key and value, following this algorithm. Using his properies:
SoapObject category_list = (SoapObject) property;
String key = category_list.getProperty("key").toString();
String value = category_list.getProperty("value").toString();
But the response from the function above (if i copy the toString() result) looks like:
Function1Response
{
return=
[
Map{
item=anyType{key=field1; value=hello; };
item=anyType{key=field2; value=web; };
item=anyType{key=field3; value=service; };},
Map{
item=anyType{key=field1; value=hello2; };
item=anyType{key=field2; value=web2; };
item=anyType{key=field3; value=service2; };},
Map{
item=anyType{key=field1; value=hello3; };
item=anyType{key=field2; value=web3; };
item=anyType{key=field3; value=service3; };}
];
}
I could iterate this response using key and value properties, but i think it would be much better (and efficient) if i could have a response like:
Function1Response
{
return=
[
Map{
item=anyType{field1=hello; };
item=anyType{field2=web; };
item=anyType{field3=service; };},
Map{
item=anyType{field1=hello2; };
item=anyType{field2=web2; };
item=anyTypefield3=service2; };},
Map{
item=anyType{field1=hello3; };
item=anyType{field2=web3; };
item=anyType{field3=service3; };}
];
}
So i could retrive them like:
SoapObject category_list = (SoapObject) property;
String field1 = category_list.getProperty("field1").toString();
String field2 = category_list.getProperty("field2").toString();
String field3 = category_list.getProperty("field3").toString();
Is that possible? I think it can be done somehow in the php server side. But i have no idea. I have been reading here and there but nobody seems to have this problem.. or a solution.
I'm sorry for the long post. I could give more code details or explain it better if i've been not clear enough.
Thanks for helping!
Upvotes: 0
Views: 2645
Reputation: 483
Well, i did find the solution.
The function in the PHP server that will publish the result in the webservice looks like:
class Functions
{
/**
*
* @return array
*/
public function Function1()
{
$con = new mysqli(server, user, pass, database);
if ($con->connect_errno) {
die(__FUNCTION__ . $con->connect_error);
}
$con->set_charset('utf8');
$arrayRet = array();
$query = 'select field1, field2, field3 from table1';
if(!$result = $con->query($query)){
die(__FUNCTION__ . $con->error);
}
while( $row = $result->fetch_array(MYSQLI_ASSOC) ){
$myClass = new TestClass();
$myClass->field1 = $row["field1"];
$myClass->field2 = $row["field2"];
$myClass->field3 = $row["field3"];
array_push($arrayRet, $myClass);
}
$result->close();
$con->close();
return $arrayRet;
}
}
I have previously created a class with all relevant attributes, as simple as:
TestClass.php
<?php
class TestClass
{
/**
* @var string
*/
public $field1;
/**
* @var string
*/
public $field2;
/**
* @var string
*/
public $field3;
}
?>
So basically we're returning an array filed with all the different instances of this class as items.
Now, in the Android Client Side (always using ksoap2 library) i receive a response like:
Function1Response
{
return=
[
Struct{field1=hello; field2=web; field3=service; },
Struct{field1=hello2; field2=web2; field3=service2; },
Struct{field1=hello3; field2=web3; field3=service3;}
];
}
and i'm able to iterate it:
//call
androidHttpTransport.call(SOAP_ACTION, envelope);
//envelope response
SoapObject result = (SoapObject) envelope.bodyIn;
//retrieve the first property, actually the array
Vector result3 = (Vector) result.getProperty(0);
//iterate
Enumeration e=result3.elements(); e.hasMoreElements();)
{
//each object from the array its an Soap Element that contanins the properties defined in the php class
SoapObject item=((SoapObject)e.nextElement());
String field1 = item.getProperty("field1").toString();
String field2 = item.getProperty("field2").toString();
String field3 = item.getProperty("field3").toString();
stringBuilder.append(
"Field1: " + codi + "\n"+
"Field2: "+ titol +"\n"+
"Field3: "+ descr +"\n"+
"******************************\n");
}
And that's it... i hope it will be useful for someone else. Thanks
Upvotes: 2