Building an MVC framework from the ground-up
Having worked with several PHP MVC frameworks now (Laraval, Nova Framework, Yii2, Joomla), I thought it would be a rewarding challenge to develop my own framework, based on what I liked about these frameworks, and what benefits me as someone who works with PHP frameworks.
The main goals of this project are;
- Light MVC framework that’s fast to learn
- Easy to work with, with minimal boiler-plate code
- Fast form-building
- Easy form validation
- Automated URL routing
With that in mind, I’ve been working on Lucid MVC; a light PHP Model-View-Controller framework designed for small projects, but with enough features and functionality to avoid repetition and too much boiler-plate code. For example, there is no manual URL routing to speak of, so URLs are automatically translated to direct to the correct controller, passing any additional parameters to the controller if the controller method accepts them.
For example, the URL:
Would instantiate the
libraryController, run the
books method, and pass in the parameters “author” and “richard-dawkins”. The route will only be successful if the controller method can be called successfully, otherwise, the user will be redirected to the
ErrorController, telling them the URL they have reached is invalid (our standard 404 “page not found” page). If the controller allows for optional parameters, then they can be omitted from the URL, and the default parameters will be used. This allows for flexible controller paths, leaving it up to the developer to handle any further validation if they require it.
Like Yii2, a layout template can be applied to the entire view, rendering the view content inside it. Different layouts can be applied in the controller before a view is rendered, or the default layout can be used.
Views themselves are fairly straight-forward. Model attributes, variables or other values are passed to the view via the controller, and can be accessed like normal variables.
Contact Form Controller
This is the controller for the contact form page at the beginning of this post. So far, models can load POST data (assigning it to the model attributes), store data, and perform data validation through a growing-list of validation filters.
Controllers can render views, and redirect to different routes. Controllers also have some basic functionality for dealing with web requests such as checking for POST data.
class ContactController extends Controller
public function __construct()
public function index()
$model = new ContactForm();
if($this->isPost() && $model->load())
$model->addValidator("email", ["email", $model->email]);
/*validates a string between 3 and 10 characters long*/
$model->addValidator("string", ["name", $model->name, 3, 10]);
if($model->validate()) //Validation success.
/*redirects to the homepage by default if no route is passed*/
$this->view->render('contact/index', ["model" => $model]);
Automated PHP file-inclusion
Because this is designed to be an MVC framework for small projects, the framework uses a custom autoload function to automatically include any PHP files when you call a new Class. So, rather than using Namespaces, every PHP file will be included automatically at the moment it is needed. For large-scale projects this might cause problems with naming conflicts, but for a library that’s designed to be quick to use and build with, it’s perfectly serviceable.
The next two features that need to be implemented are the
Database class, and the first of the Helper classes to aid in quick form-building. The Database class will be a wrapper class for PHP’s PDO extension, providing easy-to-use methods for standard database CRUD operations, and will handle variable binding automatically for the highest security and less coding.
FormHelper class will aid in building HTML forms programmatically, automatically handling the form action, various input types and options, and binding the model attributes to the form.
Database class are complete, I think the project will be complete enough to release on GitHub for anyone who wishes to use it.