Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass multiple parameters to a library in CodeIgniter?

I am making a library for CodeIgniter, and I wish to pass multiple parameters of different types (a PDO object, username and password, configurations, etc).

I know I can pass an array of all of these things, but that doesn't seem to be the best way of doing things (as $params can't ever describe what is needed).

How can I pass multiple parameters to a library?

Thanks in advance.

like image 682
Madara's Ghost Avatar asked Feb 04 '12 15:02

Madara's Ghost


People also ask

How to use library function in CodeIgniter?

To access CodeIgniter's native resources within your library use the get_instance() function. This function returns the CodeIgniter super object. Normally from within your controller functions you will call any of the available CodeIgniter functions using the $this construct: $this->load->helper('url');

How to use get_ instance in CodeIgniter?

First, assign the CodeIgniter object to a variable: $CI =& get_instance(); Once you've assigned the object to a variable, you'll use that variable instead of $this : $CI =& get_instance(); $CI->load->helper('url'); $CI->load->library('session'); $CI->config->item('base_url'); // etc.

How to load library in CodeIgniter view?

$CI->load->library('library_name');


3 Answers

There are several approaches to this particular problem. I'll list (in preferred order) ways I know to solve it:

Associative Array Arguments:

This approach is pretty flexible, as the order of the parameters doesn't matter, and it resolves a pretty big complaint many have with how PHP defines function parameters. You simply pass in the "non-default" parameters you want. This is probably the most "codeigniterish" way to do it, if that's even a thing.

class MyLibrary {

    public function __construct($params = array())
    {
        // Merge default parameter names and values,
        // with given $params array
        $params = array_merge(array(
            'server'   => 'myserver',
            'database' => 'mydatabase',
            'username' => 'myuser',
            'password' => 'mypassword'
        ), $params);

        // Create variables from parameter list
        extract($params);

        var_dump($server);
        var_dump($database);
        var_dump($username);
        var_dump($password);
    }

}

// Initialization:
$this->load->library('mylibrary', array(
    'server'   => 'server-arg1',
    'database' => 'database-arg2'
));

Numbered Arguments:

This approach replicates the typical PHP parameter paradigm (defines names, orders, and default values for all expected parameters).

class MyLibrary {

    public function __construct($params = array())
    {
        // Add relevant defaults to missing parameters
        $params = array_merge($params, array_slice(array(
            'myserver',
            'mydatabase',
            'myuser',
            'mypassword'
        ), count($params)));

        // Create variables from parameter list
        extract(array_combine(array(
            'server',
            'database',
            'username',
            'password'
        ), $params));

        var_dump($server);
        var_dump($database);
        var_dump($username);
        var_dump($password);
    }

}

// Initialization:
$this->load->library('mylibrary', array('server-arg1', 'database-arg2'));

Override the CI Loader class:

This is AT YOUR OWN RISK. Basically, the CI_Loader::_ci_init_class() method needs to be overridden with a MY_Loader class and corresponding method. These are the lines that you "don't like" (lines 1003-1012 in my install):

    // Instantiate the class
    $CI =& get_instance();
    if ($config !== NULL)
    {
        $CI->$classvar = new $name($config);
    }
    else
    {
        $CI->$classvar = new $name;
    }

The "safest" replacement that I could guess would be this:

    // Instantiate the class
    $CI =& get_instance();
    if (isset($config[1])
    {
        // With numeric keys, it makes sense to assume this is
        // is an ordered parameter list
        $rc = new ReflectionClass($name);
        $CI->$classvar = $rc->newInstanceArgs($config);
    }
    elseif ($config !== NULL)
    {
        // Otherwise, the default CI approach is probably good
        $CI->$classvar = new $name($config);
    }
    else
    {
        // With no parameters, it's moot
        $CI->$classvar = new $name;
    }

I really don't know how many things this will break, but I can almost certainly say there will be something. It's not really worth the risk. I'd STRONGLY recommend the first approach above.

Cheers!

like image 104
landons Avatar answered Oct 19 '22 20:10

landons


One can sidestep Codeigniters Loader class and instantiate objects directly. APPPATH is a Codeigniter constant.

require_once( APPPATH.'libraries/some_class.php' );
$this->Some_class = new Some_class( param_1, param_2, param_n );
$this->Some_class->do_something();

Usage is the same as if you'd loaded the Library with Codeigniters Loader class.

$this->load->library( 'some_class' )
$this->Some_class->do_something();

I personally don't like passing arrays to my classes becasue then you have to validate the contents. PHP can take care of this for you when the parameters are passed to the __construct() individually.

like image 20
T. Brian Jones Avatar answered Oct 19 '22 18:10

T. Brian Jones


From my experience with CodeIgniter, unless you modify the loader class to act differently (as you might know, in application/core/ folder is where you have to implement you custom class) there is no way (no one of that I know)

I use many external libraries (mostly api sdks or sparks) and I like to build my own config files where to set values that will be loaded into libraries when called upon them, so when I need to load libraries I just build a simple or multidimensional $params = array() according to my needs and then work with it inside library.

So in short answer, $this->load->library('lib_name', $params) is the only way I am aware of.

like image 1
Alex Avatar answered Oct 19 '22 18:10

Alex