Understanding MVC in PHP
Pages: 1, 2, 3, 4, 5, 6
The New Way
By bringing everything into an MVC framework, I could make my life a lot easier. Compare the following code:
<?php
class myapp extends FR_Auth_User
{
public function __construct()
{
parent::__construct();
}
public function __default()
{
// Do something here
}
public function delete()
{
}
public function __destruct()
{
parent::__destruct();
}
}
?>
Notice that this code has no apparent concern with connecting to a database, verifying the user is logged in, or outputting anything. The controller handles all of this.
If I wanted to authenticate against LDAP, I could create FR_Auth_LDAP. The controller could recognize certain output methods (such as $_GET['output']) and switch to the PDF or SOAP presenter on the fly. The event handler, delete, handles only deleting and nothing else. Because the module has an instance of the FR_User class, it's easy to check which groups that user is in, etc. Smarty, the template engine, handles caching, of course, but the controller could also handle some caching.
Switching from the old way to the MVC way of doing things can be a completely foreign concept to some people, but once you have switched, it's hard to go back. I know I won't be leaving the comforts of my MVC framework anytime soon.
Creating the Foundation
I'm a huge fan of PEAR and the PEAR_Error class. PHP 5 introduced a new class, Exception, which is almost a drop-in replacement for PEAR_Error. However, PEAR_Error has a few extra features that make it a more robust solution than Exception. As a result, the framework and foundation classes will use the PEAR_Error class for error handling. I will use Exception, however, to throw errors from the constructors, as they cannot return errors.
The design goals of the foundation classes are:
- Leverage PEAR to quickly add features to the foundation classes.
- Create small, reusable abstract foundation classes that will enable developers to build applications quickly within the framework.
- Document all foundation classes using phpDocumentor tags.
- Prepend all classes and global variables with
FRto avoid possible variable/class/function collisions.
The class hierarchy will look something like this:
FR_Objectwill provide the basic features that all objects need (including logging, genericsetFrom(),toArray()).FR_Object_DBis a thin layer to provide child classes a database connection, along with other functions such classes might need.FR_Object_Webis a thin layer that provides session and user information for web-based applications.FR_Moduleis the base class for all applications (AKA "modules," "model," etc.) built in the framework.FR_Authis the base authentication class, which will allow for multiple authentication mechanisms.FR_Auth_Useris an authentication class to use in modules that require a valid, logged-in user.FR_Auth_Nois a dummy authentication class used for modules that require no authentication.
FR_Presenteris the base presentation class (the view) that will handle loading and displaying the applications after they have run.FR_Presenter_smarty: the presentation layer will include the ability to load different drivers. Smarty is a great template class that has built in caching and an active community.FR_Presenter_debugis a debugging presentation layer that developers can use to debug applications.FR_Presenter_restis a REST presentation layer that developers can use to output applications in XML.
Looking at the foundation classes, you can start to see the separate parts of the MVC framework. FR_Module provides for the basic needs of all of the modules (Model), FR_Presenter provides a way to display applications arbitrarily in different formats (Views). In the next part of this series I will create the controller, which will bring all of our foundation classes together in a single place.
