A Better CodeIgniter Model Structure?

I have been working with CodeIgniter for PHP for some time now, and although I would now use Laravel if I were to restart the project I’m working on, I am heavily tied to CodeIgniter for now.

PHP Model Design

I have a problem / question. After exploring other languages like Go (GoLang) and even a little Ruby, I’ve noticed something that is odd about PHP and perhaps specific to CodeIgniter.

The models aren’t really models.. they’re more like interfaces for the database for just pulling data, this almost seems like a waste and unnecessary.

I am trying to figure out if it is better practice to define the model and assign each variable to it after pulling the data and accessing like a normal object. Like so:

class Product_m extends CI_Model {

    public $name;
    private $_table = 'products';

    public function __construct()
    {
        parent::__construct();
    }

    public function get($id)
    {
        $query = $this->db->get_where($this->_table, 'id', $id); //this is off memory.. just an example
        $result = $query->result();
        $this->name = $result[0]->name;
    }

    public function get_all($shop_id)
    {
        $query = $this->db->get($this->_table);
        $result = $query->result();
        // loop and build array of objects...      
    }
}

But here’s the problem

For a function where it returns an array of objects like $this->get_all() then this won’t work because in CI you load the model once.


So I figured I could perhaps create a separate class (or extend the class) which is literally just like a struct and defines the class. That way I can instantiate the class whenever I want to create arrays of objects if I wanted plus return objects to my controller, just like returning $this.

So here I am

class Sp_Product {

    public      $id                 =       0; 
    public      $name;
    public      $images             =       array();

}

class Product_m extends CI_Model {

    private $_table = 'products';
    private $_model = 'Sp_Product';

    public function __construct()
    {
        parent::__construct();
    }

    public function get($id)
    {
        $query = $this->db->get_where($this->_table, 'id', $id); //this is off memory.. just an example
        $result = $query->result();

        $product = new $this->_model;
        $product->id = $id;
        $product->name = $result[0]->name;

        return $product;
    }

    public function get_all($shop_id)
    {
       $query = $this->db->get($this->_table);
       $result = $query->result();

       $products = array();
       foreach($result as $p)
       {
          $product = new $this->_model;
          $product->id = $p->id;
          $product->name = $p->name;
          $products[] = $product;
       }

       return $products;
    }

}

What do you think?

I have tested this and it works. Here’s what I think the Pros and Cons are:

Positives

  1. I can set my application models separately to my database models. Meaning if I change a column name in my db, then I don’t need to change as much code in my application.
  2. This will allow for clearer programming practices moving forward.
  3. It gives some structure and consistency.
  4. Removes ambiguity if you don’t have access to the database for some reason.
  5. I can use other class types in my models. For example if I have nested data models: product > images. I can load in a Sp_Product_Image for each image in my Sp_Product objects.

Negatives

  1. It will be extra work to setup.
  2. There may be additional memory used by using this approach as the model will be loaded as well as returning an object back or an array of new objects. Thoughts and advice on this?

I feel I may have outgrown CodeIgniter and this is where it’s showing it’s weakness. I am very open to other suggestions, and if my terminology is mixed up please do let me know.


Source: oop

Leave a Reply