Madara Uchiha Madara Uchiha - 1 month ago 10
PHP Question

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.

Answer

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!

Comments