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->instanceredefinition 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?
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.phpwithinapplication/corefolder, contain your own base class, eg: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 :
Both attemps can be considered legal, atm. Because, the fact that : 1) there is no consistency checking (something like
instanceof CI_Controllerin PHP 5, oris_afor PHP4) within CI bootstrap, 2) And, CI not force you to returning anything from a controller action method (aResponseobject, 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')andget_instance()->load->database()within those arbitrary class.