Discover the Model-View-Controller Architecture
What's Software Architecture ?
Developing a website from scratch is a step that every developer has already experienced in his life. You have an idea for a project, or a request from a customer, and you open your favorite text editor, starting to program all its features.
Instinctively, the first idea would be to create one HTML (Or PHP) file per page of your website. Let's take the example of developing a blog. You should need three separate files :
• Home.php : Home page, which presents all your articles.
• Search.php : Performs a search among existing articles.
• Article.php : Display the content of a particular article.
The disadvantage of such an approach is that all your files are isolated from each other. Let's take the example of the first two files (Home.php and Search.php) : Their content is identical, except that the first one will display all existing articles, while the second one will filter them. But everything else, from the database connection to the layout of the retrieved articles, will be strictly identical.
In order to better understand this, I propose to analyze the Search.php file.
<?php
try {
$pdo = new PDO("mysql:host=localhost;dbname=DataBase", "root", "root");
} catch(PDOException $exception) {
exit();
}
$query = $pdo->prepare("SELECT Title, Content FROM Articles WHERE Title LIKE :title");
$query->bindValue("title", "%" . htmlspecialchars($_GET["Search"]) . "%", PDO::PARAM_STR);
$query->execute();
if($articles = $query->fetchAll()) { ?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<title> Blog </title>
</head>
<body>
<?php foreach($articles as $row) { ?>
<h3> <?= $row["Title"]; ?> </h3>
<p> <?= $row["Content"]; ?> </p>
<?php } ?>
</body>
</html>
<?php } else { ?>
<script> window.location.replace("Index.php"); </script>
<?php }
?>
If you are used to programming in PHP, you should easily understand this program. You will notice that to create the file Home.php, just replace line 11 with this :
$query = $pdo->exec("SELECT Title, Content FROM Articles");
And delete the next two lines. Everything else in the code is exactly the same.
The reason I told you about this method is that it is used by most beginning developers, including myself a few years ago… In absolute terms, you can design a project this way, but you will then encounter many constraints.
First of all, with each new page you add, you will have to take an existing page and modify it to suit your needs. Moreover, if you want to change the background color of your site, you will need to modify each file one by one… Imagine if you have several dozen different pages. I'll give you an example of a design change, but you'll have the same problem if you need to change the database connection, or any other parameter that is duplicated in each of your files… Not very practical, is it ?
All these constraints are imposed by the basic architecture of this project. Luckily, there are other ways of doing things, which allow us to get around most of these limitations. Probably the best known is the Model-View-Controller (MVC) architecture, which is massively used in the web development world.
Models, Views and Controllers
Just as a cook must learn a new recipe before starting a new dish, the creation of a project respecting MVC architecture implies knowing the basics of how it works. This will give us a frame of development, allowing us to structure our project in a coherent and intelligent way.
Concretely, the MVC architecture is based on the observation we saw at the beginning of this article : All PHP files look alike, and are always composed of three distinct parts. First of all, we have to perform one or more database queries, (Lines 5 to 13 of the Search.php file) then process and verify these data, (Lines 15 and 30) and finally, generate an HTML page, according to the recovered data. (Lines 16 to 29)
Previously, all of this was programmed into one file. From now on, I'm going to ask you to separate them into three separate files.
First, the Models folder containing the database connections. For my part, I use a different file for each table in my database, and I include functions to add, retrieve, or modify information about that table. (And only this table)
<?php
function getArticles($search) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=DataBase", "root", "root");
} catch(PDOException $exception) {
exit();
}
$query = $pdo->prepare("SELECT Title, Content FROM Articles WHERE Title LIKE :title");
$query->bindValue("title", "%" . htmlspecialchars($search) . "%", PDO::PARAM_STR);
$query->execute();
return $query->fetchAll();
}
?>
Next, the Views folder, containing the different views of your project. A view is a file generating dynamic HTML code, but containing the bare minimum of PHP. It can therefore contain conditions and loops, but will not do complex operations or redirection.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<title> Blog </title>
</head>
<body>
<?php foreach($articles as $row) { ?>
<h3> <?= $row["Title"]; ?> </h3>
<p> <?= $row["Content"]; ?> </p>
<?php } ?>
</body>
</html>
These checks will be made in the Controllers folder. This is the conductor, and links the other two files. His role is to check the data received by the models, and to call up the corresponding view.
<?php
require("Models/Articles.php");
if($articles = getArticles($_GET["Search"]) require("Views/Search.php");
else echo '<script> window.location.replace("Index.php"); </script>';
?>
As you have noticed, the controller will only include the models it needs. Depending on the data retrieved, the controller will make various checks, (Here, it just tests if the requested item exists, but you will usually have other checks) and will have to include the presentation view of the items, or a possible redirection in case of an error.
At this point, there is only one step left : The router. This is the entry point to any MVC architecture, and is intended to include a controller. Usually, the router takes a parameter (Transmit via URL) that indicates which controller to call.
<?php
$action = htmlspecialchars($_GET["Action"]);
if($action == "Blog") require("Controllers/Blog.php");
else if($action == "Article") require("Controllers/Article.php");
else require("Controllers/Error.php");
?>
Note that the router will only test the value of its parameter, to determine which controller to call. All other checks (including the presence or not of the requested item in the database) will be done in the controller in question, which may redirect in case of a problem.
Here are the minimum requirements for any project using the MVC architecture. Next to these, you will usually find a Public folder, containing all your static resources. (CSS/JavaScript files, …) Personally, I also create a Requests folder, containing the files generating the results of AJAX requests. This is of course optional, and you are free to add as many folders as you want.
Doing More to Do Less
At this point, you may be wondering how MVC architecture will revolutionize your website. If it works so well without it, why would you want to break it down into models, views and controllers ?
The main advantage of this architecture is the time required to develop new features. Imagine that you want to integrate a ranking of the most read articles. Just add a new function in one of the models, create a new controller, and indicate it in the router. You don't have to change your other models or views, because you will use the same ones as on the other pages.
Moreover, it forces you to split your code efficiently. If you have an error when you retrieve your articles in the database, you know that it comes from the Articles.php file in the Models folder. Having experienced this, it's much more convenient than having to look for an error in a 500-line file, where the database connection, verification of the results obtained, and display of variables are mixed up.
If you don't believe me, I invite you to create a basic blog, as you would have done with the method presented at the beginning of this article. Once this is done, try programming it again, using the MVC architecture. You will then get the same project, but with a much clearer and more understandable code. I really invite you to start such an exercise, in order to realize the advantages of the MVC architecture !
The MVC architecture is a way to organize a project, by separating the files according to their roles : The models, which manage the connection to the database, the views, which generate the HTML page, and finally the controllers, which make the link between the retrieved data and the result on the screen. Such a methodology allows to simplify the development, while improving the maintenance of your future website. Its use has exploded over the last few years, so much so that many modern frameworks use it today. (Symfony, ASP.Net, …) Its use will require an effort of understanding at the beginning, but be sure that the investment will be profitable for all your future projects.
Écrit par Pythony le 12/01/2020.