dphdh395195 2012-09-19 16:58
浏览 56
已采纳

使用Zend Lib通过SOAP发送php复杂类型数组,并使用Android KSOAP2客户端检索它

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!

  • 写回答

1条回答 默认 最新

  • 普通网友 2012-09-27 09:45
    关注

    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 + "
    "+ 
                        "Field2: "+ titol +"
    "+ 
                        "Field3: "+ descr +"
    "+
                        "******************************
    ");
            }
    

    And that's it... i hope it will be useful for someone else. Thanks

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog