Can somebody explain to me when it's a good practice to use models in CI? An article in wikipedia was referring to CI models as "entirely optional and are rarely needed" is that true in any way?
问题:
回答1:
Say you needed to call a function called get_user_info
that retrieves the users info from a database. You could have a function like this:
class Home extends Controller {
function __construct() {
parent::__construct();
}
function index() {
$user = $this->get_user_info($_SESSION['user_id']);
echo "Hello " . $user['first_name'];
}
function get_user_info($user_id) {
$query = $this->db->query("SELECT * FROM users WHERE user_id = ?", array($user_id));
return $query->row_array();
}
}
However, what if you needed to call get_user_info
on another page?
In this scenario you would have to copy and paste the function into every page making it difficult to maintain if you have lots of pages (what if you needed to change the query to JOIN onto another table?)
This also goes against the don't repeat yourself principle.
Models are meant to handle all data logic and representation, returning data already to be loaded into views. Most commonly they are used as a way of grouping database functions together making it easier for you to change them without modifying all of your controllers.
class User extends Model {
function __construct() {
parent::Model();
}
function get_user_info($user_id) {
$query = $this->db->query("SELECT * FROM users WHERE user_id = ?", array($user_id));
return $query->row_array();
}
}
In the above we have now created a model called user
. In our home controller we can now change the code to read:
class Home extends Controller {
function __construct() {
parent::__construct();
}
function index() {
$this->load->model('user');
$user = $this->user->get_user_info($_SESSION['user_id']);
echo "Hello " . $user['first_name'];
}
}
And now you can change your get_user_info
function without having to change X number of controllers that rely on the same function.
回答2:
No!! That's not true. Models are used as a layer between your controller and the database. MVC best practice is a subjective matter at best. People use it in different ways. A framework like CodeIgniter is great because it allows that level of flexibility. Other frameworks are much more strict. I'm general I try and keep my controllers very small and specific and put lots of code (db interaction and parsing results etc) in a model.
回答3:
Well a "model" reprensents data, most likely from a database (meaning your rows are returned from the database and the model holds the send data, simply said). There is no need to use the database layer given by CI - that is true- you can replace with another if you like, but that they are "rarely used" is simply not true.
回答4:
You should be using models to avoid replicating code (don't repeat yourself). I think most (nearly all) applications built with codeigniter would use models of some sort.
Perhaps the article is referring to the active record class, which is optional to use in models. Active record I find to be good for create, update and deletion but you'll most likely need sql for any slightly complex reads. It's worth noting that it's not just databases you can use in models. Web services or flat files or whatever source of data can be used in a model.
I've been thinking of the models as a database layer only. They should not be, this creates bloating in your controllers. Using fat-controllers will slow you down in the end. Put your entire model structure in the model if you can and simply use the controller for logic.
回答5:
There is a principle called 'fat model / skinny controller' which you might like to look at that suggests that the weight of your processing should be done in model files as oppose to controllers. This backs up the don't repeat yourself principle as outlined by @fire above as well as promoting re-use.
I have found using this principle that I have ended up with a set of common, re-usable controllers that each use a set of re-usable models as well as, occasionally, project specific controllers used only once per site. As well as this I have cross dependency between models. I would not be able to re-use quite as frequently as I do without following the above principle and encapsulating as much processing as I can in the models.
This subject gets a lot of discussion online so there is a lot of information to look at but it seems that on the Code Igniter boards it is recommended by the more experienced users.
I have to add that 'entirely optional and are rarely needed' is generally not the case, I would say that this is plain wrong in anything but the most simple cases - the most simple cases being static pages which don't integrate with a database and just consist of a few loaded views, but even then using a model with a function in to retrieve a common set of views for each page would be advisable.
回答6:
Models are for business logic(in ideal cases.. might be for debate, some people put buiness logic in controller) and DB connectivity in the MVC framework.
Read codeigniter user guide for more info on models.
http://codeigniter.com/user_guide/general/models.html
回答7:
This my Large model has lot of methods.
class Shortcode_model extends CI_Model {
public function __construct() {
parent::__construct();
$this -> load -> library('session');
}
/**
* Misc functions
*/
/**
* read keyword .
*
* @return void
* @author Chinthaka
**/
public function read($id) {
$this -> db -> select();
$this -> db -> from('short_code');
$this -> db -> where('id', $id);
$query = $this -> db -> get();
$result = $query -> row();
$shortcode = new stdClass();
$shortcode->id = $result->id;
$shortcode->code = $result->code;
$shortcode->aggregator = $result->aggregator;
$shortcode->mo_pp_id = $result->mo_pp_id;
$shortcode->mt_free_pp_id = $result->mt_free_pp_id;
$shortcode->mt_bill_pp_id = $result->mt_bill_pp_id;
$shortcode->partner_role_id = $result->partner_role_id;
$shortcode->partner_role_pass = $result->partner_role_pass;
$shortcode->product_id = $result->product_id;
$shortcode->billable = $result->billable;
// $shortcode->created = $result->created;
// $shortcode->changed = $result->changed;
$shortcode->status = $result->status;
//print_r($shortcode);
return $shortcode;
}
public function read_operator($telco_id){
$this -> db -> select();
$this -> db -> from('operator');
$this -> db -> where('telco_id', $telco_id);
$query = $this -> db -> get();
$result = $query -> row();
$operator = new stdClass();
$operator->id = $result->id;
$operator->code = $result->telco_id;
$operator->name = $result->telco_name;
return $operator;
}
/**
* create keyword .
*
* @return void
* @author Chinthaka
**/
public function create($arr_data) {
$this -> db -> insert('short_code', $arr_data);
//$stock['stock_id'] = $this->db->insert_id();
//return $query->result();
//return $keywords;
}
/**
* update keyword .
*
* @return void
* @author Chinthaka
**/
public function update($arr_data) {
$this -> db -> where('id', $arr_data['id']);
$this -> db -> update('short_code', $arr_data);
}
/**
* delete keyword .
*
* @return void
* @author Chinthaka
**/
public function delete($id) {
$this -> db -> where('id', $id);
$this -> db -> delete('short_code');
}
/**
* get all enabled shortcodes stored in the database.
*
* @return $shortcodess
* @author Chinthaka
**/
public function all_enable_shortcodes() {
$this -> db -> select();
$this -> db -> from('short_code');
$this -> db -> where('status', 'enable');
$this -> db -> order_by("code");
$query = $this -> db -> get();
$result = $query -> result_array();
//echo mysql_num_rows($result);
$shortcodes = array();
foreach ($result as $row) {
$shortcode = $this -> read($row['id']);
array_push($shortcodes, $shortcode);
}
/*while($data = $this->db->call_function('fetch_row', $result )) {
$shortcode = $this->read($data['id']);
array_push($shortcodes,$shortcode);
}*/
return $shortcodes;
}
/**
* check shortcode is exist.
*
* @return boolean
* @author Chinthaka
**/
function is_exists($shortcode, $id = 0) {
$this -> db -> where('code', $shortcode);
if ($id > 0) {
$this -> db -> where('id <>', $id);
}
$query = $this -> db -> get('short_code');
if ($query -> num_rows() > 0) {
return true;
} else {
return false;
}
}
public function get($short_code_id)
{
$query = $this->db->query('select * from short_code where id=?', array($short_code_id));
log_message('debug', $this->db->last_query());
return $query->row();
}
}