CodeIgniter Forums

Full Version: Recommended OO approach when using CI
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Sorry if I am driving people a little crazy with all the questions Huh  I am in the process of learning CI and want to try and do things the "correct" way from the start.

I come from a procedural background and I am trying hard to adopt a more OO approach.  This question might be more PHP related than it is CI related, I'm not sure.

Anyway, I am wondering what is the best approach when working with controllers and models in CI.  I see an awful lot of examples on the web like this:

PHP Code:
$this->load->model('customer_model');

$customer $this->customer_model->get(123); // Get the customer
$colours $this->customer_model->get_colours(123); // Get the customers favourite colours

echo $customer->email// Print their email address

// Print their favourite colours
foreach ($colours as $colour) {
 
   echo $colour;
}

$success $this->customer->save(123, array('email' => '123@456.com')); // Change their email address in the DB

if (!$success) {
 
  die('Something went wrong');


The above is an approach I am very familiar with, and seems similar to many of the examples I see in tutorials and so on.  However I can't help feeling a better approach is:

PHP Code:
$this->load->model('customer_model');

try {

 
   $this->customer_model->get(123); // Get the customer
 
   $this->customer_model->get_colours(123); // Get the customers favourite colours

 
   echo $this->customer_model->get_value('email'); // Print their email address

 
   // Print their favourite colours
 
   foreach ($this->customer_model->get_value('colours') as $colour) {
 
       echo $colour;
 
   }

 
   $this->customer_model->set_value('email''123@456.com'); // Change their email address

 
   $this->customer->save(); // Save their email address to the DB

 
   // Or even chaining:
 
   $this->customer_model->set_value('email''123@456.com')->save();

} catch (
Exception $e) {
 
   die$e->getMessage() );


Please let me know what you think. I appreciate your thoughts.
I am sorry but I am not really certain what you are asking, however what I like to do now, is to have an additional logic layer. I have my controllers only call libraries (logic layer). Those libraries call models. The model interacts with the database.

The benefit I have found is that say I need to change the way I record customer details. I change the library (making sure any existing functions return the expected values) and the model to deal with the new database structure. All in one place. Any calls to the library still work as expected and I do not have to trawl through every controller where a customer detail is called.

The added library level allows me to put logic into the process, whilst keeping the model as thin as possible. So I have a thin(ish) controller, fat library, super thin model.

Also, form validation is done in the library too, so any changes to formats, messages etc are all done in one place too. Also, I never echo anything from a controller. That is very bad (except in the case of an ajax controller of course).

Controller example
PHP Code:
<?php
defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Customer extends CI_Controller {
 
  public function view($customer_code)
 
  {
 
     $this->load->library('customers/customer_library');

 
     ...

 
     $customer $this->customer_library->get_customer_details();
 
     if (!$customer )
 
          
         show_error
('The customer you requested could not be displayed.'401'ACCESS DENIED');
 
        exit;
 
     }
 
     $page_data['customer'] = $customer;

 
     ...

 
     $this->load->view('customers/customer_view'$page_data);
 
  }


Library example
PHP Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 

class 
Customer_library {
 
  
   
public function __construct()
 
  {
 
     $this->CI=&get_instance();
 
  }
 
  
    public 
function get_customer_details($customer_code)
 
   {
 
     $this->CI->load->model('mysql_database/customers/customer_model');

 
     ...
 
     Might also want to check permissions or other logic
      
...

 
     $customer $this->CI->customer_model->get_customer($customer_code);
 
     ...

 
     return $customer;
 
  }


Model example
PHP Code:
<?php
defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Customer_model extends CI_Model {
 
  public function get_customer($customer_code)
 
  {
 
     $results FALSE;
 
     $this->db->from('customers');
 
     $this->db->where(etcetc.);
 
     $query $this->db->get();
 
     if ($query->num_rows() == 1)
 
     {
 
        $results $query->row_array();
 
     }
 
     return $results;
 
  }


Although it can feel a bit long winded in the first draft, it gets really super quick for updates and changes and development.

I am not certain this is the 'best' way but the beauty of CI is it is very forgiving allowing you to work however you feel is best. This way is the way I currently prefer for my sites.

Hope that helps,

Paul.

PS Forgot to mention, suppose I needed to check permissions in the customer library, I would call the permissions_library to check the permissions, so again any permissions changes can all be done in one place, not needing to refer to every call to permissions dotted around. I have no problems with libraries calling libraries at all.
PS Just realised my previous answer does not really address your OO query at all. Sorry. Left the answer in rather than deleting because it took me ages :-(