简体   繁体   English

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

[英]Send a php complex type array via SOAP using Zend Lib and retrieving it with Android KSOAP2 client

I'm trying to return an associative array in a PHP function. 我正在尝试在PHP函数中返回关联数组。 This function retrieves some data from MySQL and is published in a WebService using Zend Library. 该函数从MySQL检索一些数据,并使用Zend库将其发布在WebService中。

This function looks like: 该函数如下所示:

Functions.php 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): 然后,我还有另一个PHP文件,可让我通过SOAP(使用Zend Lib)访问该函数:

Server.php 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客户端,则可以使用Web服务并按以下方式访问返回的数组:

<?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. 好的,现在我的问题是我不是在编写php客户端,而是在编写Android客户端。 I'm using the ksoap2 library to achieve it. 我正在使用kso​​ap2库来实现它。 With this library i'm able to handle "normal arrays" with the pare key and value, following this algorithm . 使用此库,我可以按照此算法使用pare键和值来处理“普通数组”。 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: 但是上面函数的响应(如果我复制toString()结果)看起来像:

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. 我认为可以在php服务器端以某种方式完成。 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! 感谢您的帮助!

Well, i did find the solution. 好吧,我确实找到了解决方案。

The function in the PHP server that will publish the result in the webservice looks like: PHP服务器中将结果发布到Web服务中的函数如下所示:

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 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: 现在,在Android客户端(始终使用kso​​ap2库)中,我收到如下响应:

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 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM