How to create a simple MVC framework in PHP

Today we will create an MVC framework in PHP. This will be very simple but will allow us to understand how this works.
MVC was originally used over the GUI desktop applications, but recently (not so recent) with the growth and maturity of web languages, started appearing some frameworks drawn with this architecture.
I think the starter of this web vision was David Heinemeier Hansson the creator of Ruby On Rails, It was him that lunched the MVC for the first time to the web.
But let’s get started on our MVC tutorial.
MVC in a nutshell it’s a efficient, clean and fast way to separate your code from you HTML, or the UI if your prefer.
MVC means, Model – View – Controller.
Model: Responsible for the data management like SQL databases and SELECT, UPDATE, DELETE,etc…
View: Shows the UI, html, css, javascript and so on
Controller: The brain and heart of MVC architecture, this is were all comes in, the controller is the middle man between the view and the model.
Here’s a simple scheme how all this works.

1º the user types http://www.umsite.com/blog
2º The framework go fetch out controller blog.php
3º The controller will process and format the information
4º The model will deliver to the controller the data needed from the controller.
5º The controller will format this information and pass it to the view.
6º Finally the controller will invoke the view and output the UI.
Not all MVC frameworks works such as this, but this is pretty much the basic of our framework in this tutorial.
So let get started.
Define our data structure
./my_mvc
./my_mvc/application
./my_mvc/application/controller
./my_mvc/application/model
./my_mvc/application/view
That’s pretty much explanatory
/.htaccess
Before anything else, we must create an .htaccess file, this file will redirect all HTTP request to index.php.
RewriteEngine On
RewriteBase /my_mvc/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Note: You must have mod_rewrite activated in out Apache configuration.
/index.php
Index.php like I said before it’s our gateway , everytime we access an URL the .htaccess file will redirect us to index.php and this file will load our framework API (which in our case is a very small footprint), and API will be responsible for calling the controllers and so on.
//Define our site URL
define("BASE_PATH", "http://localhost");
//Define our basepath
$path = "/my_mvc";
//Take the initial PATH.
$url = $_SERVER['REQUEST_URI'];
$url = str_replace($path,"",$url);
//creates an array from the rest of the URL
$array_tmp_uri = preg_split('[\\/]', $url, -1, PREG_SPLIT_NO_EMPTY);
//Here, we will define what is what in the URL
$array_uri['controller'] = $array_tmp_uri[0]; //a class
$array_uri['method'] = $array_tmp_uri[1]; //a função
$array_uri['var'] = $array_tmp_uri[2]; //a variavel
//Load our base API
require_once("application/base.php");
//loads our controller
$application = new Application($array_uri);
$application->loadController($array_uri['controller']);
/application/base.php
This class is vital, since that it’s from here that our controllers will get loaded, and such as views and models.
class Application
{
var $uri;
var $model;
function __construct($uri)
{
$this->uri = $uri;
}
function loadController($class)
{
$file = "application/controller/".$this->uri['controller'].".php";
if(!file_exists($file)) die();
require_once($file);
$controller = new $class();
if(method_exists($controller, $this->uri['method']))
{
$controller->{$this->uri['method']}($this->uri['var']);
} else {
$controller->index();
}
}
function loadView($view,$vars="")
{
if(is_array($vars) && count($vars) > 0)
extract($vars, EXTR_PREFIX_SAME, "wddx");
require_once('view/'.$view.'.php');
}
function loadModel($model)
{
require_once('model/'.$model.'.php');
$this->$model = new $model;
}
}
You may not believe it, but we already have our ultra-slim-light MVC framework done.
That wasn’t so hard wasn’t ?
Now let’s start using it, to create a controller, model and two views.
/application/controller/blog.php
This will be the name of our controller, so every time we access http://localhost/my_mvc/blog/ the class Application by now has already filtered the URL from index.php, and it will now load our blog.php.
class Blog extends Application
{
function __construct()
{
$this->loadModel('model_blog');
}
function index()
{
$articles = $this->model_blog->select();
$data['articles'] = $articles;
$this->loadView('view_blog',$data);
}
function add($title="")
{
$data['title'] = $title;
$this->loadView('view_blog_add',$data);
}
}
If you notice, in the class constructor we can define what will be the model that we will use, in this case i’ve choose model_blog, and this model will be loaded from ./application/model/model_blog.php as you will see further on.
By default, this class will run everything inside index(), but if we access http://localhost/my_mvc/blog/add, our class Blog will invoke our add function. Simple ?
Inside every class function we can call model functions as well, or define variables that will be used inside our views.
On a close inspection over index() we will see that:
- Call a function select from model_blog.php
- Creates an array with vars
- Loads a view in and variable array
/application/model/model_blog.php
class model_blog extends Application
{
function __construct()
{
//do something, DB connections, etc..
}
function select()
{
return array("title 1","title 2","title3");
}
}
This class is responsible for the DB treatment, in our model I’ve created a simple select() function that will simulate the return of DB array with rows.
/application/view/view_blog.php
<html> <head> <title>My Blog</title> </head> <body> <h1>My Blog</h1> <?foreach($articles as $article):?> <h3><?=$article?></h3> <?endforeach?> </body> </html>
/application/view/view_blog_add.php
<html> <head> <title>My Blog</title> </head> <body> <h1>My Blog</h1> <h3>Title:</h3> <input type="text" value="<?=$title?>"> </body> </html>
Finally, we have two views like I’ve said earlier. They will show or final “result”, in HTML of course.
Download the sample framework.
16 Responses to “How to create a simple MVC framework in PHP”
Leave a Reply

Aurelio on May 11th, 2009
Cool. Gostava de ver o mesmo tut em ruby (on rails of course).
Igor Leroy on May 11th, 2009
Henrique, muito bom o artigo. Estou me baseando nele para montar um aqui tambem.
tarsis Lima on June 3rd, 2009
Henrique gostei bastante do artigo,mas tenho uma dúvida:
Neste caso é exibido um modulo por vez, mas como ficaria se eu precisasse exibir varios modulos diferentes na mesma pagina?
por exemplo se na mesma pagina eu quisesse listar 5 noticias(1º modulo) e o nome dos ultimos usuarios cadastrados (2º modulo)?
Henrique B. on June 7th, 2009
Olá Tarsis,
desculpa pela demora na resposta, estive um pouco ausente.
Respondendo a tua questão, a solução passaria por acrescentar uma função no model “model_blog.php” , como por exemplo “get_lastest_users()” , depois no controller “blog.php” usavas o metodo
Depois era so carregar a variável $latest_users para a variável $data
E por fim era usar essa informação na tua view.
Em alternativa poderias criar outro model (como disseste) e carrega-lo no __construct();
Esta seria a solução ideal, caso necessitasses de usar esta informação em mais partes do site, evitavas assim, repetir código.
Espero ter respondido a tua questão.
Willian on August 24th, 2009
Bom dia, adorei o seu tutorial! Muito bom!
Sou do Brasil e gostaria pedir permissão para traduzir o seu artigo e postar no meu blog. Citando toda o seu blog como referência, claro.
Um abraço, muito obrigado!
Samuel Corradi on September 21st, 2009
Olá Henrique! Belo tutorial! Depois dá uma olhada nisso aqui http://www.phpcoupe.com
Não é um MVC, mas faz as mesmas coisas que um MVC mas de forma diferente.
Se tiver tempo – e interesse – gostaria de saber sua crítica.
Abraços!
Henrique Gosch on February 20th, 2010
Bom dia,
Qual o motivo desse tutorial ser em inglês?
Atenciosamente,
Henrique Gosch
Max on March 1st, 2010
esse http:// www phpcoupe com Da a apariencia de ser algo legal(cool), porem com essa licença este projeto não vai longe…
Principalmente quando existem bilhoes de frameworks, ultraleves ou ‘lites’ bem maduros.
meus dois centavos.
abraços.
Francisco Souza on March 3rd, 2010
Salve Henrique, parabéns pelo post
Dando uma melhorada, é possível ainda passar mais variáveis pela URL, com um simples ajuste na classe Application: http://pastebin.com/UzEdwQF0 (note a linha 25).
Assim, basta mudar o index.php para passar uma lista de variáveis para a classe Application, e não mais apenas uma variável: http://pastebin.com/YaA2abjs (linhas 20 à 25).
Abraços!
Diorges on March 15th, 2010
Olá Henrique, estou criando minha propria framework, e gostaria de tirar uma duvida com vc, mas claro, só se vc souber…
Quando eu requisito o URI ex.: site.com/controlador/metodo/variavel1/variavel2
Minha duvida é a seguinte, quando passo mais de 1 variavel pro metodo, como eu resgato elas?
eu consegui pegar somente a primeira variavel, gostaria de pegar mais de uma variavel para o metodo
meu_metodo($var1, $var2, $var3)
{
}
onde:
site.com/controlador/metodo/var1/var2/var3
saberia me responder?
Obrigado!
Deluxe Blog Tips on April 23rd, 2010
Nice tutorial. The directory structure and the code looks like the CodeIgniter framework, doesn’t it? But I love the way you explain all of these “hard” thing (for beginners). Thank you very much for sharing.
Henrique B. on April 23rd, 2010
Yes, in fact I was inspired on CI for this tutorial. I’m glad you like it
Jordan on June 2nd, 2010
I’m getting a undefined index error…I’m running the script on a wamp server. Any ideas?
Henrique B. on June 20th, 2010
Hi Jordan, that normally means PHP is trying to find an array index value but can’t find it.
Make sure you have mod-rewrite active on you apache, and you have .htaccess in the main folder as well
Julio B. on July 20th, 2010
Sou meio que iniciante em PHP, mas gostaria de saber quanto a performance, sei que é uma aplicaçao exemplo e tal, mas seria viavel a utilização desse codigo em sites com grande acesso?
nasier on August 13th, 2010
It’s amazing tutorial, I have one question:
from the base.php we will get url like this mysite.com/controller/method/param, i am wondering how to hide the method from the url for so it can be mysite.com/controller/param ?
thanks for sharing .