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 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题