CodeIgniter and NuSOAP

What are we going to do?

We’ll use NuSOAP to create a webservice using CodeIgniter and consume it using CI also.

In this tutorial, we’ll use “cds” table from “cdcol” database bundled from XAMPP. “cds” table content looks like this:

cds table content

cds table content

Download NuSOAP here : https://sourceforge.net/projects/nusoap/
Extract “lib” folder from nusoap-0.9.5.zip into your CI “application/libraries/”. We’ll create simple library warper for NuSoap.
Now, enter your CI “application/libraries/” folder and create a new file named “Nusoap_library.php”. Here’s the content:


We'll use default controller from CI, i.e. Welcome.php. We'll create two webservice endpoints: one for getting info about a CD based in it's "id" and one for getting all of CDs.
All of webservice data types definition, registration and implmentation will be placed inside Wellcome controller's "__construct()" function. Here's the complete code for "__construct()" function:

    function __construct() 
    {
        parent::__construct();

        $this->load->library("Nusoap_library"); //load the library here
        $this->nusoap_server = new soap_server();
        $this->nusoap_server->configureWSDL("MySoapServer", "urn:MySoapServer");
        $this->nusoap_server->wsdl->schemaTargetNamespace = 'urn:MySoapServer';

        //DATA TYPES
        $this->nusoap_server->wsdl->addComplexType(
            'Cd',
            'complexType',
            'struct',
            'all',
            '',
            array(
                'id' => array('name' => 'id', 'type' => 'xsd:integer'),
                'jahr' => array('name' => 'jahr', 'type' => 'xsd:integer'),
                'interpret' => array('name' => 'interpret', 'type' => 'xsd:string'),
                'titel' => array('name' => 'titel', 'type' => 'xsd:string')
            )
        );

        $this->nusoap_server->wsdl->addComplexType(
            "CdArray",
            "complexType",
            "array",
            "",
            "SOAP-ENC:Array",
            array(),
            array(
                array("ref"=>"SOAP-ENC:arrayType","wsdl:arrayType"=>"tns:Cd[]")
            ),
            "tns:Cd"
        );

        //REGISTRATION
        $this->nusoap_server->register(
            'getCdInfo',
            array('id' => 'xsd:integer'),  //parameters
            array('return' => 'tns:Cd'),  //output
            'urn:MySoapServer',   //namespace
            'urn:MySoapServer#getCdInfo',  //soapaction
            'rpc', // style
            'encoded', // use
            'Get CD Info by ID' //description
        );

        $this->nusoap_server->register(
            'getCds',
            array(),  //parameters
            array('return' => 'tns:CdArray'),  //output
            'urn:MySoapServer',   //namespace
            'urn:MySoapServer#getCds',  //soapaction
            'rpc', // style
            'encoded', // use
            'Get all CDs' //description
        );

        //IMPLEMENTATION
        function getCdInfo($id)
        {
            $ci =& get_instance();
            $ci->db->where('id', $id);
            $qcd = $ci->db->get('cds');
            if ($qcd->num_rows()>0) {
                return $qcd->row_array();
            } else {
                return false;
            }
            
        }

        function getCds()
        {
            $ci =& get_instance();
            $qcd = $ci->db->get('cds');
            if ($qcd->num_rows()>0) {
                $ret_val=array();
                $i=0;
                //echo "masuk hasil";
                foreach ($qcd->result_array() as $row) {
                    //var_dump($row);
                    $ret_val[$i]=$row;
                    $i++;
                }
                //var_dump($ret_val);
                return $ret_val;
            } else {
                return false;
            }
            
        }
    }

The first step is loading the library and configuring your webservice:

$this->load->library("Nusoap_library"); //load the library here
$this->nusoap_server = new soap_server();
$this->nusoap_server->configureWSDL("MySoapServer", "urn:MySoapServer");
$this->nusoap_server->wsdl->schemaTargetNamespace = 'urn:MySoapServer';

We'll define a new data type for our CD info based on "cds" table structure:

        $this->nusoap_server->wsdl->addComplexType(
            'Cd',
            'complexType',
            'struct',
            'all',
            '',
            array(
                'id' => array('name' => 'id', 'type' => 'xsd:integer'),
                'jahr' => array('name' => 'jahr', 'type' => 'xsd:integer'),
                'interpret' => array('name' => 'interpret', 'type' => 'xsd:string'),
                'titel' => array('name' => 'titel', 'type' => 'xsd:string')
            )
        );

Now, our complex type that will hold list of CDs (array of CDs).

        $this->nusoap_server->wsdl->addComplexType(
            "CdArray",
            "complexType",
            "array",
            "",
            "SOAP-ENC:Array",
            array(),
            array(
                array("ref"=>"SOAP-ENC:arrayType","wsdl:arrayType"=>"tns:Cd[]")
            ),
            "tns:Cd"
        );

After finished defining all needed data types, we'll register all needed webservice endpoint.
First endpoint is "getCdInfo" to get info about a CD based on it's "id". It takes one parameter ("id") and return a "Cd" type.

        $this->nusoap_server->register(
            'getCdInfo',
            array('id' => 'xsd:integer'),  //parameters
            array('return' => 'tns:Cd'),  //output
            'urn:MySoapServer',   //namespace
            'urn:MySoapServer#getCdInfo',  //soapaction
            'rpc', // style
            'encoded', // use
            'Get CD Info by ID' //description
        );

Second endpoint is "getCds" to get all stored CD in the "cds" table. It takes no parameter and return an array of CDs.

        $this->nusoap_server->register(
            'getCds',
            array(),  //parameters
            array('return' => 'tns:CdArray'),  //output
            'urn:MySoapServer',   //namespace
            'urn:MySoapServer#getCds',  //soapaction
            'rpc', // style
            'encoded', // use
            'Get all CDs' //description
        );

Registration is finished, now onto the implementation. Here's the code:

        function getCdInfo($id)
        {
            $ci =& get_instance();
            $ci->db->where('id', $id);
            $qcd = $ci->db->get('cds');
            if ($qcd->num_rows()>0) {
                return $qcd->row_array();
            } else {
                return false;
            }
            
        }

        function getCds()
        {
            $ci =& get_instance();
            $qcd = $ci->db->get('cds');
            if ($qcd->num_rows()>0) {
                $ret_val=array();
                $i=0;
                foreach ($qcd->result_array() as $row) {
                    $ret_val[$i]=$row;
                    $i++;
                }
                return $ret_val;
            } else {
                return false;
            }
            
        }

Pay attention, that I'm using "get_instance()" in order to query the database because we can't call "$this" inside these endpoint functions.
Next, we'll edit the default "index()" function, replace it with these:

        public function index()
    {
        $this->nusoap_server->service(file_get_contents("php://input")); //shows the standard info about service
    }

You may try accessing your webservice from your browser and see how it looks

WSDL schema

WSDL schema

webservice description

webservice description

Now, some fixing!

Before accessing our webservice via a SOAP client, we need to fix NuSoap library. Open "application/libraries/lib/nusoap.php", go to line 6132 and comment that line so it would look like this:

//$this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");

If you didn't do this fixing step, you'll get a blank result when calling an endpoint that return an array of data. Further testing using SoapUI will reveal some error like this:

A PHP Error was encountered

Severity: Notice Message: Array to string conversion Filename: lib/nusoap.php Line Number: 6132

Fixing is done, now we'll test it.
For simplicity reason, we'll put our client inside our Welcome controller. Here's the code:

    public function testClient()
    {
        $wsdl = 'http://localhost/ci_soap/?wsdl';
        $this->load->library("Nusoap_library"); //load the library here

        $client = new nusoap_client($wsdl, 'wsdl');

        $res1 = $client->call('getCdInfo', array('id'=>1));
        var_dump($res1);

        $res2 = $client->call('getCds');
        var_dump($res2);
    }

As you can see, the code is quite simple, $res1 will contain output from "getCdInfo" endpoint

array(4) {
  ["id"]=>
  int(1)
  ["jahr"]=>
  int(1990)
  ["interpret"]=>
  string(16) "Ryuichi Sakamoto"
  ["titel"]=>
  string(6) "Beauty"
}

and $res2 will contain an array of CDs as a result from calling "getCds".

array(3) {
  [0]=>
  array(4) {
    ["id"]=>
    int(1)
    ["jahr"]=>
    int(1990)
    ["interpret"]=>
    string(16) "Ryuichi Sakamoto"
    ["titel"]=>
    string(6) "Beauty"
  }
  [1]=>
  array(4) {
    ["id"]=>
    int(4)
    ["jahr"]=>
    int(2001)
    ["interpret"]=>
    string(13) "Groove Armada"
    ["titel"]=>
    string(33) "Goodbye Country (Hello Nightclub)"
  }
  [2]=>
  array(4) {
    ["id"]=>
    int(5)
    ["jahr"]=>
    int(1997)
    ["interpret"]=>
    string(13) "Bran Van 3000"
    ["titel"]=>
    string(4) "Glee"
  }
}

Here's the complete source code of our controller, in case you missed something:

defined('BASEPATH') or exit('No direct script access allowed');

class Welcome extends CI_Controller
{

    function __construct() 
    {
        parent::__construct();
        //$this->load->model(''); //load your models here

        $this->load->library("Nusoap_library"); //load the library here
        $this->nusoap_server = new soap_server();
        $this->nusoap_server->configureWSDL("MySoapServer", "urn:MySoapServer");
        $this->nusoap_server->wsdl->schemaTargetNamespace = 'urn:MySoapServer';

        //DATA TYPES
        $this->nusoap_server->wsdl->addComplexType(
            'Cd',
            'complexType',
            'struct',
            'all',
            '',
            array(
                'id' => array('name' => 'id', 'type' => 'xsd:integer'),
                'jahr' => array('name' => 'jahr', 'type' => 'xsd:integer'),
                'interpret' => array('name' => 'interpret', 'type' => 'xsd:string'),
                'titel' => array('name' => 'titel', 'type' => 'xsd:string')
            )
        );

        $this->nusoap_server->wsdl->addComplexType(
            "CdArray",
            "complexType",
            "array",
            "",
            "SOAP-ENC:Array",
            array(),
            array(
                array("ref"=>"SOAP-ENC:arrayType","wsdl:arrayType"=>"tns:Cd[]")
            ),
            "tns:Cd"
        );

        //REGISTRATION
        $this->nusoap_server->register(
            'getCdInfo',
            array('id' => 'xsd:integer'),  //parameters
            array('return' => 'tns:Cd'),  //output
            'urn:MySoapServer',   //namespace
            'urn:MySoapServer#getCdInfo',  //soapaction
            'rpc', // style
            'encoded', // use
            'Get CD Info by ID' //description
        );

        $this->nusoap_server->register(
            'getCds',
            array(),  //parameters
            array('return' => 'tns:CdArray'),  //output
            'urn:MySoapServer',   //namespace
            'urn:MySoapServer#getCds',  //soapaction
            'rpc', // style
            'encoded', // use
            'Get all CDs' //description
        );

        
        //IMPLEMENTATION
        function getCdInfo($id)
        {
            $ci =& get_instance();
            $ci->db->where('id', $id);
            $qcd = $ci->db->get('cds');
            if ($qcd->num_rows()>0) {
                return $qcd->row_array();
            } else {
                return false;
            }
            
        }

        function getCds()
        {
            $ci =& get_instance();
            $qcd = $ci->db->get('cds');
            if ($qcd->num_rows()>0) {
                $ret_val=array();
                $i=0;
                foreach ($qcd->result_array() as $row) {
                    $ret_val[$i]=$row;
                    $i++;
                }
                return $ret_val;
            } else {
                return false;
            }
            
        }
    }
    
    public function index()
    {
        $this->nusoap_server->service(file_get_contents("php://input")); //shows the standard info about service
    }

    public function testClient()
    {
        $wsdl = 'http://localhost/ci_soap/?wsdl';
        $this->load->library("Nusoap_library"); //load the library here

        $client = new nusoap_client($wsdl, 'wsdl');

        $res1 = $client->call('getCdInfo', array('id'=>1));
        var_dump($res1);

        $res2 = $client->call('getCds');
        var_dump($res2);
    }
}

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Trackbacks and Pingbacks: