Lesson 1 - MVC architecture explained

PHP MVC MVC architecture explained

Welcome to the first lesson of a course where we'll create a fully object-oriented blog in PHP, step by step (CMS = content management system). We'll use the MVC architecture, which we'll explain in today's tutorial, to structure our simple CMS. In the following lessons, we're going to program a website with proper URLs, registration and log-in functionality, a WYSIWYG editor, and a contact form. We'll also create several more useful classes to make adding more features simple.

I'm always surprised when I see others use a huge amount of code of third-party content when they could do the same exact things easily. Our code will be done in a minimalist fashion, and the entire system will consist only of a small amount of short, yet efficient classes.

The course assumes you are familiar with the Basics of object-oriented programming in PHP.

MVC architecture

MVC is a very popular architectonic pattern that is widely used mainly in web applications, although it originated from desktop apps. It's a key part of popular web frameworks, e.g. Zend/Symfony for PHP, Ruby On Rails for Ruby, or MVC for ASP .NET. Personally, I can't imagine how anyone could go about developing complex websites without the MVC architecture, or a similar pattern.

The principle

The main idea behind the MVC architecture is to separate logic from output. Meaning that it rids us of what is commonly known as "spaghetti code", which is often present when there are both logical operations and output rendering in a single file (class). So the file contains database queries, logic (e.g. PHP operations), and cluttered HTML tags. In other words, everything is all tangled up like spaghetti. I'm sure you've seen it before, I'll show you an example of "spaghetti" code that we used to discourage its use in previous articles:

// Our project will not look anything like this
$result = mysql_query("select * from question", $connection);
if (!mysql_num_rows($result))
        echo '<p>There is no survey yet.</p>';
else
{
        echo '<ul>';
        while ($row = mysql_fetch_array($result))
        if ($survey == $row['survey_id'])
                echo '<li>' . $row['survey_id'] . ': ' . $row['content'] . ' (selected)</li>';
        else
                echo '<li><a href="surveys.php?survey=' . $row['survey_id'] . '">'
                .$row['survey_id'] . ': '
                .$row['content'] . '</a></li>';
        echo '</ul>';
}

The code is obviously hard to give maintenance to, not to mention extend. It's poorly highlighted since our IDE doesn't understand it ver well, the HTML part is not formatted properly, and its tree structure is confusing. Our goal is to make the logical part of the source code look be actual code (e.g. PHP), and the output to be an HTML page with the least amount of logic as possible. With this in mind, the code shown above could be split into 2 files (an HTML template and a PHP script). Ideally, we would incorporate other PHP classes, as well. We'll show you what an application structured with MVC looks like very soon.

Components

The entire application is made up of three kinds of components,Models, Views (templates), and Controllers, which is what MVC stands for. There is no strict definition of the MVC architecture, so you may come across multiple definitions (MVC also overlays the MVP architecture definition). The important thing to subdivide the components into the aforementioned three groups.

As you may have guessed, components are represented by classes in object-oriented applications and can be inherited from abstract ancestors. Usually, the only view that is incorporated is an HTML template. Let's go over each one of the MVC component groups.

Model

The model component of MVC architecture The model contains logic and everything related to it. It can be calculations, database queries, validations and so on. The model is not aware of any sort of output whatsoever. Its role is to receive parameters from the outside and return the data respectively. Just to be clear, when we say parameters here, we don't mean the URL address or any similar parameters from the user. The model doesn't know where the data in the parameters came from nor how the data will be formatted, and/or printed out.

We'll program without what is known as ORM (object-relational mapping) since PHP doesn't have anything like it, and third-party solutions are unnecessarily heavy on performance. Aside from that, PHP has excellent data structures that provide everything we need when combined with dynamic typing. If you don't already know what ORM is, don't worry about it, we won't be using it anyway. We'll also apply the concept of object managers in our application. In other words, the application's logic will be separated into sections like UserManager, ArticleManager, and so on. These managers contain methods for retrieving necessary data from the database or modifying said data. For example, a method that selects a username and profile information that are needed to display a user's profile. Another method could be one that retrieves a password hash from the database in order to authenticate a user login, or perhaps one that returns a given article to said user. UserManager could also have methods to work with users, e.g. password length validation, and character set validation. The "manager logic" doesn't have to be limited to database access, we could also add internal validations, calculations, and so on.

Now that we know more of what models do, let's move onto the view.

View

The view component of MVC architecture The View displays application output to a user. In most cases, the output is a phtml template, including an HTML page and a scripting language's tags. In doing this, we are able to add variables, use loops and conditions in the template. Again, we'll keep our application as simple as possible and only use things that are provided by PHP. There are special languages designed for formatting templates (like Smarty). However, it doesn't make much sense for us to use a third-party templating language since PHP is a templating language itself. Regardless, templating languages allow us to write a code in a way that preserves the HTML structure.

We usually have many views for user entities, including but not limited to:

  • user_register,
  • user_login,
  • user_profile,
  • among others.

The user_profile view is common for all the users and the only difference between them is the data passed (based on the user that we're currently displaying). This data is then inserted into the HTML template's elements.

We could also nest views into one another to avoid redundant code (useful for layout templates, menu templates, article template, etc).

Aside from being a template, a view serves as an "output viewer" as well. Meaning that it exclusively contains the tiny amount of logic needed to format the output, e.g. a condition that checks whether a user has filled their username in before printing it or a loop printing comments.

Similarly, as the Model doesn't know where the data came from, the View only cares about displaying said data to the user.

Controller

The controller component of MVC architecture Now, let's go over the last one so you can put it all together in your mind. The controller works somewhat like a man in the middle, who communicates with the user, the model, and the view. Meaning that it holds the entire system together and wires the components. You'll understand it much better once we take look at a website's life cycle. As you now know, there are several ways of assembling an MVC application. In most cases, each entity has one controller, i.e. UserController, ArticleController, so on and so forth.

Website life cycle

The life cycle of an MVC website starts out with a user who enters a website address with certain parameters in his browser. The user tells us, based on the given parameters, which subpage he/she wants us to display. Imagine that we wanted to display a user's information who happens to have an id of 15. The URL address with said data could look like this:

http://www.domain.com/user/detail/15

First and foremost, the request is handled by a so-called router, which determines the controller we are calling based on the URL parameters. I'm sure we would come up with many ways of determining the controller's name. However, we'll keep things as simple as possible and do it without any manual routing. What we'll do instead is pass the controller's name as the first parameter in a URL address. In this specific case, we'd call the UserController and pass the "detail" and 15** parameters to it.

The appropriate controller recognizes what we want from it based on the URL parameters. In this case, it would recognize that we want it to display the user's details. It calls a model, which looks for the user in the database and returns its details. Then, the controller may call another method on the model, e.g. calculate the user's age. The controller saves these values into variables. At the very end, we render the view. We determine a view's name based on an action we're currently processing. Variables containing the required data are passed onto the view. At this point, the controller has done what the user requested, it obtained data from the model based on the request parameters, and it passed them onto the view.

The view receives the data from the controller and inserts it into a pre-made template. The page is then sent back to the user, who doesn't even realize the magnificence of what just happened on the server :)

Here's a diagram of the entire scenario:

MVC architecture

Now, we've successfully obtained the separation of logic and output. Views are like HTML pages, whereas models are in our server-side scripting language (e.g. PHP). Now we can have clear code that is separated logically.

The MVC architecture also makes design decisions throughout a project to make development easier. When we write logic, it belongs to the model. Whereas formatting and styling take a place in views. What the user wants is determined in controllers. In a worst case scenario, we'd have 3 different problems in 3 different places, separated in a way that doesn't allow them to mix and complicate the troubleshooting process.

On the next lesson, .htaccess, autoloader and the common controller, we'll start up with the first part of our system, which will be the router.


 

 

Article has been written for you by David Capka
Avatar
Do you like this article?
3 votes
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn College The author learned IT at the Unicorn College - a prestigious college providing education on IT and economics.
Activities (8)

 

 

Comments

To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

No one has commented yet - be the first!