oym
oym

Reputation: 7083

PHP & Codeigniter - how to pass parameters to a model?

I am using the following code to initialize a model from within my controller:

$this->load->model('model_name');

Is it possible to modify the above line somehow so that the model constructor recieves a parameter? I want to use the following code in the model constructor:

function __construct($param_var) {
   parent::Model();

   $this->$param_var = $param_var; //I'm not even sure this works in PHP..but different issue
}

This would be very helpful so that I can reuse my model classes. Thanks.

UPDATE: (from one of the answers, my original question is solved..thanks!) Just to explain why I wanted to do this: the idea is to be able to reuse a model class. So basically to give a simple example I would like to be able to pass an "order_by" variable to the model class so that I can reuse the logic in the model class (and dynamically change the order-by value in the sql) without having to create a separate class or a separate function.

Is this poor design? If so could you please explain why you wouldn't do something like this and how you would do it instead?

Upvotes: 19

Views: 33642

Answers (5)

Randy Lam
Randy Lam

Reputation: 689

I am using CI ver 3.X, so what I am about to say is it will work for Codeigniter 3.X (and I haven't checked ver 4+ yet).

When I went thru the source code of the function model() in file system/libraries/Loader.php, noticed that it does not support loading the model with construct parameters. So if you want to make this happen you have to change the source code (bold, I know, and I just did).

Down below is how I did it.

1. Firstly, replace line 355

$CI->$name = new $model();

with some modifications:

$_args_count = func_num_args();
if(3 < $_args_count){
    $refl = new ReflectionClass($model);
    $CI->$name = $refl->newInstanceArgs(array_slice($_args_count, 3));
}else{
    $CI->$name = new $model(); // origin source code 
}

2. Load the model with a bit difference:

$this->load->model("model_name", "model_name", false, $param_var); // where amazing happens

Now you can have $this->model_name as you wished.

Upvotes: 0

antelove
antelove

Reputation: 3348

In model

<?php

/* Load Model core model */
/* BASEPATH = D:\xampp\htdocs\ci_name_project\system\ */
include BASEPATH . 'core\\Model.php';

class User_model extends CI_Model {

    /* Properties */
    private $name;


    /* Constructor parameter overload */
    public function __construct($name) {
        $this->set_name($name);
    }    


    /* Set */
    public function set_name($name) {
        $this->name = $name;
    }


    /* Get */
    public function get_name() {
        return $this->name;
    }

}

in controller

<?php

class User_controller extends CI_Controller {

    public function index() {

        /* Load User_model model */
        /* APPPATH = D:\xampp\htdocs\ci_name_project\application\ */
        include APPPATH . 'models\\User_model.php';

        $name = 'love';

        /* Create $object_user object of User_model class */
        $object_user = new User_model($name);     

        echo $object_user->get_name(); // love

    }

}

Upvotes: 4

vinothvetrivel
vinothvetrivel

Reputation: 109

Instead of using DataMapper i suggested to use IgnitedRecord because that the DataMapper is no longer maintained more over it has been replaced into Ruby

Upvotes: 1

jimyi
jimyi

Reputation: 31191

You can't pass parameters through the load function. You'll have to do something like:

$this->load->model('model_name');
$this->model_name->my_constructor('stuff');

In the model:

function my_constructor($param_var) {
...
}

Response to update:

You could just pass the order_by value when you're calling your model function. I'm assuming in your controller action, you have something like $this->model_name->get($my_id); Just add your order_by parameter to this function. IMO this makes your model logic more flexible/reusable because the way you were doing it, I assume setting order_by in the constructor will set the order_by value for every function.

Upvotes: 23

Dom M.
Dom M.

Reputation: 3869

I see your reasoning for this, but may I suggest looking at Object-Relational Mapping for your database needs. There is a user-made ORM library for CodeIgniter called DataMapper that I've been using lately. You can use tables in your controllers as objects, and it may be a better fit for your problem.

Upvotes: 3

Related Questions