• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
CI SOAP Server Problem

#1
[eluser]JanDoToDo[/eluser]
Hey guys,

Am currently making a SOAP server with CI and have this:

Code:
class Web_server extends Controller {
    
    function getOrder($username, $password)
    {
        $user = 'delagua';
        $pass = 'admin123!';
        
        if ($user == $username AND $pass == $password) :
            //$query = $this -> ci -> db -> get('country_iso');
            $query = $this -> db -> select('o.*')
                                    -> from('orders AS o')
                                    -> where(array())
                                    -> get();
            $results = $query -> result_array();
            
            foreach ($results as $order) :
                $items = array();
                foreach ($order as $k => $item) :
                    $items[$k] = array($item, 'string');
                endforeach;
                
                $query = $this -> ci -> db -> select('od.product_id, od.product_quantity')
                                        -> from('orders_products AS od')
                                        -> where('order_id', $order['order_id'])
                                        -> get();
                $products = $query -> result_array();
                foreach ($products as $product) :
                    foreach ($product as $k => $prod) :
                        $pr[$k] = array($prod, 'string');
                    endforeach;
                    
                endforeach;
                $prods[] = array($pr, 'struct');
                $items['products'] = array($prods, 'struct');
                $orders[$order['order_id']] = array($items, 'struct');
            endforeach;
            
            return $orders;
        
            //return 'validation success';
            
        else :
            throw new SoapFault("Server", "Validation Failed");
        endif;
    }
    
    function index()
    {
        ini_set('soap.wsdl_cache_limit', 0);
        ini_set('soap.wsdl_cache_ttl', 0);
        $server = new SoapServer('http://www.domain.org/assets/server.wsdl');
        $server -> setClass('Web_server');
        $server -> handle();
    }

When I run the client I get this error returned:

SoapFault exception: [SOAP-ENV:Server] Call to a member function get() on a non-object in...

However, when I take out the DB requests, it works fine. I tried instantiating the CI super object inside the function but that didnt work.

Anyone have any ideas?

#2
[eluser]n0xie[/eluser]
Did you try replacing:
Code:
$query = $this -> ci -> db ->

with
Code:
$query = $this->db->

#3
[eluser]JanDoToDo[/eluser]
Yep. And all variations of such!

#4
[eluser]n0xie[/eluser]
Are you sure?

Because in your example I see 2 different queries. One written with $this->db-> and the other with $this->ci->db-> ...

#5
[eluser]JanDoToDo[/eluser]
Yeah no i did its just because ive tried combinations of everything - just forgot to change that back when i copied the code.

To make it clearer - when i was testing i commented out ALL of that code anyway, and just used the one liner at the top which is currently commented

---> ($this -> ci -> db _> get('country_iso')Wink

so that i could make sure i wasnt making a silly error anywhere. This is what i tried all the different combinations with.

#6
[eluser]JanDoToDo[/eluser]
To clarify, i'm testing this code below as the getOrder inserted as above function and it gives me this error:

SoapFault exception: [env:Receiver] Call to a member function get() on a non-object in /var/www/html/public_html/devel/application/controllers/web_client.php:20 Stack trace: #0 /var/www/html/public_html/devel/application/controllers/web_client.php(20): SoapClient->__soapCall('getOrder', Array) #1 [internal function]: Web_client->index() #2 /var/www/html/public_html/devel/system/codeigniter/CodeIgniter.php(233): call_user_func_array(Array, Array) #3 /var/www/html/public_html/devel/index.php(139): require_once('/var/www/html/p...') #4 {main}

Code:
function getOrder($username, $password)
    {
        $this -> ci =& get_instance();
        $user = 'delagua';
        $pass = 'admin123!';
        
        if ($user == $username AND $pass == $password) :
            $query = $this -> db -> get('country_iso');

        
            return 'validation success';
            
        else :
            throw new SoapFault("Server", "Validation Failed");
        endif;
    }

Without the db query, it returns "validation success";

#7
[eluser]JanDoToDo[/eluser]
Anyone have any ideas?

#8
[eluser]JanDoToDo[/eluser]
Hey guys.

This is for everyones use and is a solution to the above.

Problem - CI doesn't seem to make SOAP integration particularly easy. In particular, the database class caused SOAP Server to fail everytime I tried to run it.

Solution - Create the functions required in the constructor of the SOAP server and call the index function from the SOAP client. Add each of the required functions in the SOAP server setup. If using the database class, replace each instance with raw PHP database functions i.e. mysql_connect, mysql_query etc. It doesn't seem to be able to load the database class and if the function is made in the constructor, it cannot reference "$this -> db" as $this is not the super object. Even if a new reference is made (which solves the reference to the db class) it causes the SOAP server to fail. My settings are as follows for when it crashed, and a sample of how i overcame it.

Settings:
Code:
$db['default']['active_r'] = TRUE;
$db['default']['pconnect'] = FALSE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = "";


My code:

Code:
class Web_server extends Controller {

    function Web_server()
    {
        parent::__construct();
        
        function getOrders($parameters)
        {
            $username = $parameters -> username;
            $password = $parameters -> password;
            
            $user = 'xxx';
            $pass = 'xxx';
    
            $dbuser = 'xxx';
            $dbpass = 'xxx';
            $conn = mysql_connect('localhost', $dbuser, $dbpass) or die ('Error connecting to mysql');
            
            $dbname = 'delagua';
            mysql_select_db($dbname);
            
            if ($user == $username AND $pass == $password) :
                $sql = 'SELECT o.*, u.user_email FROM orders AS o LEFT JOIN users as u ON u.user_id = o.customer_id';
                if ($order_query = mysql_query($sql)) :
                    while ($order_row = mysql_fetch_array($order_query)) :
                        $order = $order_row['order_id'];
                        $cust = $order_row['user_email'];
                        $date = $order_row['order_date'];

                        $product_sql = 'SELECT od.product_id, od.product_quantity FROM orders_products AS od WHERE order_id = ' . $order;                        
                        if ($product_query = mysql_query($product_sql)) :
                            while ($product_row = mysql_fetch_array($product_query)) :
                                $data['getOrdersReturn']['remoteComment'][] = array(
                                                                                    'orderID'             => $order,
                                                                                    'customerID'         => $cust,
                                                                                    'date'                 => (string)$date,
                                                                                    'productID'         => $product_row['product_id'],
                                                                                    'productQuantity'     => $product_row['product_quantity']
                                                                                    );
                            endwhile;
                        else :
                            $data['getOrdersReturn']['remoteComment']['productID'] = 'No products found';
                        endif;
                        
                    endwhile;
                else :
                    $data['getOrdersReturn']['remoteComment'] = 'No order';
                endif;
                return $data;
            else :
                throw new SoapFault("Server", "Validation failed for username '$username'.");
            endif;
        }
        
        function getEnquiries($parameters)
        {
            $username = $parameters -> username;
            $password = $parameters -> password;
            
            $user = 'xxx';
            $pass = 'xxx';
    
            $dbuser = 'xxx';
            $dbpass = 'xxx';
            $conn = mysql_connect('localhost', $dbuser, $dbpass) or die ('Error connecting to mysql');
            
            $dbname = 'delagua';
            mysql_select_db($dbname);
            
            if ($user == $username AND $pass == $password) :                
                $data['getEnquiriesReturn']['enquiryInfo'][] = array(
                                                                    'enquiryID'         => 12,
                                                                    'customerID'         => 34,
                                                                    'date'                 => date('Y-m-d'),
                                                                    'enquiryType'         => 'From contact page',
                                                                    'enquiryComment'     => 'I thought this was a test enquiry'
                                                                    );
                return $data;
            else :
                throw new SoapFault("Server", "Validation failed for username '$username'.");
            endif;
        }
    }
    
    function index()
    {
        ini_set('soap.wsdl_cache_limit', 0);
        ini_set('soap.wsdl_cache_ttl', 0);
        $server = new SoapServer('http://www.domain.org/assets/wsdlfile.wsdl');
        $server -> addFunction('getOrders');
        $server -> addFunction('getEnquiries');
        $server -> handle();
    }
}

#9
[eluser]JanDoToDo[/eluser]
i.e. The basic format is, with all my code stripped out

Code:
class Server extends Controller {

    function __construct()
    {
        parent::__construct();
        function get_function1($parameters)
        {
            // Perform actions with $parameters (its an object an so is referenced with $parameters -> item name)
            // If you are doing database interaction (which presumably you WILL be) it doesn't seem to be possible to use the CI db class as it causes
            // the soap server to fail. As such use mysql_connect                    
            $conn = mysql_connect('localhost', $dbuser, $dbpass) or die ('Error connecting to mysql');
            mysql_select_db($dbname);
            
            // Perform functions and set soap faults
            if (xxx condition) {
                // Do all the database work
                $sql = 'SELECT * FROM tablename';
                if ($order_query = mysql_query($sql)) :
                    while ($order_row = mysql_fetch_array($order_query)) :
                        // Get all the data you want
                    endwhile;
                endif;
                // Send back the data as an array as specified in the WSDL
                return $data
            } else {
                throw new SoapFault("Server", "XXX condition not satisfied");
            }
        }
        
        function get_function2($parameters)
        {
            // Perform actions for function 2
        }
    }
    
    function index()
    {
        // Make sure the wsdl file is not cached by the user
        ini_set('soap.wsdl_cache_limit', 0);
        ini_set('soap.wsdl_cache_ttl', 0);
        
        $server = new SoapServer(url-path-to-wsdl-file);
        // Add each of the function you want
        $server -> addFunction('get_function1');
        $server -> addFunction('get_function2');
        // Serve
        $server -> handle();
    }
}

#10
[eluser]abbasmn[/eluser]
to use soapserver in your controller you should use an empty constructor and put parent::Controller() in a function. please see below:
Code:
class Ws_server extends Controller
{
    private $test;
    function  __construct()
        {
            
        }
    function my_server()
    {        
        try
        {
    
        ini_set("soap.wsdl_cache_enabled", "0");
           $server = new SoapServer("http://localhost/Hello.wsdl",
          array('soap_version' => SOAP_1_2));
           $server->setClass("Ws_server");
           $server->handle();
                      
            }
        catch (SoapFault $exception)    
        {
                echo $exception;      
          }
    }
    
    public function hello($someone)
        {
        //this function is called by client and is in Hello.wsdl
        return "Hello".$someone." My QUEUE:".$this-> my_q();
        
        }

    private function my_q()
    {
        parent::Controller();
           $this->load->model('search_model','');
           $this->test= $this->search_model->get_queue();    
           return $this->test;
    }
            
}


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


Users browsing this thread:
1 Guest(s)


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2019 MyBB Group.