Reputation: 7083
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
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
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
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
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
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