Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CodeIgniter base classes, why is that?

A lot of frameworks out there decided to use this approach: force the user to extend a base controller class (if you want to create a new controller) or to extends a base model class (if you want to create a new model).

Let's take a look at the code of CodeIgniter's controller base class:

/**
 * Constructor
 */
public function __construct()
{
    self::$instance =& $this;

    // Assign all the class objects that were instantiated by the
    // bootstrap file (CodeIgniter.php) to local class variables
    // so that CI can run as one big super object.
    foreach (is_loaded() as $var => $class)
    {
        $this->$var =& load_class($class);
    }
    $this->load =& load_class('Loader', 'core');

    $this->load->initialize();

    log_message('debug', "Controller Class Initialized");
}

What does it do? Well, as far as I can see, it just allows us to use $this->load->... for example.

Let's take a look at the __get() magic method of the model base class:

/**
 * __get
 *
 * Allows models to access CI's loaded classes using the same
 * syntax as controllers.
 *
 * @param   string
 * @access private
 */
function __get($key)
{
    $CI =& get_instance();
    return $CI->$key;
}

It does exactly the same thing. Now what does this way of doing things bring?

PRO

  • You can access useful CI classes by $this->....

CONS

  • You have to force the user to extends the base class
  • You have to force the user to call the parent::__construct() in the class construct
  • get_instace() is reserved
  • $this->instance redefinition cause a fatal error
  • You have basically repeated the same code both in the Model base class and the Controller base class

Now let's take a look at another approach:

Create a static class, such as App that do all the things the base controller does: For example, $this->load->... would be App::load->....

Now consider pros and cons again:

PRO

  • You can access useful CI classes by App::....
  • You don't have to force the user to extends the base class
  • You don't have to force the user to call the parent::__construct() in the class construct
  • no methods name or properties name are reserved
  • You can use App both in the Model and in the Controller

CONS

  • You have no more the $this-> sexy syntax???

QUESTION

Here it comes the real question: would be the second a better or worse approach compared to the CI one? Why?

like image 462
Shoe Avatar asked Nov 04 '22 02:11

Shoe


1 Answers

PRO

  • You can access useful CI classes by App::....
  • You don't have to force the user to extends the base class
  • You don't have to force the user to call the parent::__construct() in the class construct no methods
  • name or properties name are reserved

This not entirely valid. CI never force dev to extend the base class. All core framework functionality could be easily extended. You can have MY_Controller.php within application/core folder, contain your own base class, eg:

Front_Controller extends CI_Controller{
  // Share common properties or functionalities across front/public controllers here
}

Admin_Controller extends CI_Controller{
  // Share common properties or functionalities across administrative controllers here
}

Then, parent::parent_method() is very common in PHP. Mostly you'll have this syntax elsewhere, if you really use OO design in your application. This enable you to adding functionality to a subclass without loosing the inherited functionality from parent class.

So answering your question :

Here it comes the real question: would be the second a better or worse approach compared to the CI one? Why?

Both attemps can be considered legal, atm. Because, the fact that : 1) there is no consistency checking (something like instanceof CI_Controller in PHP 5, or is_a for PHP4) within CI bootstrap, 2) And, CI not force you to returning anything from a controller action method (a Response object, like in SF, for example).

Thats to say, you can have an arbitrary class act as a controller. In fact you didn't need to wrap core Controller functionality within a static class, no one stoped you to use get_instance()->load->library('foo') and get_instance()->load->database() within those arbitrary class.

like image 64
toopay Avatar answered Nov 09 '22 06:11

toopay