Skip to main content
PHP Backend Development Tutorial
CHAPTER 14 Beginner

MVC Architecture in PHP

Updated: May 14, 2026
25 min read

# CHAPTER 14

MVC Architecture in PHP

1. Introduction

If you throw your database queries, your HTML layout, and your form validation all into a single file, your code will quickly become a tangled, unreadable nightmare known as "Spaghetti Code." To build large, maintainable software, the industry uses a design pattern called MVC (Model-View-Controller). In this chapter, we will learn how to architect a professional PHP application by strictly separating our logic, data, and presentation.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the Model, View, and Controller concepts.
  • Understand how data flows through an MVC application.
  • Refactor "spaghetti code" into an organized directory structure.
  • Grasp the architectural foundation of major PHP frameworks (like Laravel).

3. Beginner-Friendly Explanation

Imagine a high-end restaurant.
  • The Controller (The Waiter): The waiter takes your order (the HTTP Request). They don't cook the food, and they don't grow the ingredients. They just manage the workflow. They take the order to the kitchen.
  • The Model (The Chef): The chef receives the order from the waiter. The chef goes to the pantry (the Database), grabs the ingredients, and prepares the food (Data Logic). They hand the finished dish back to the waiter.
  • The View (The Plating/Atmosphere): The waiter takes the dish to a specialized plating station where it is made to look beautiful (HTML/CSS). Finally, it is served to the customer.
MVC ensures that the waiter never cooks, and the chef never talks to the customer. Everyone has one specific job.

4. The Anatomy of MVC

M - Model (Data): Responsible for interacting with the database. It handles all INSERT, SELECT, and UPDATE queries. It contains the business rules.

V - View (Presentation): Responsible for the UI. It contains the HTML, CSS, and minimal PHP just to echo variables. It never contains database connection code.

C - Controller (Logic): The middleman. It receives the URL request from the Router, asks the Model for data, and passes that data to the View to be rendered.

5. Step 1: The Model

Let's build a feature to show user profiles. First, we create a Model to handle the database.

models/UserModel.php

php
123456789101112131415
<?php
class UserModel {
    private $pdo;

    public function __construct($pdo_connection) {
        $this->pdo = $pdo_connection;
    }

    public function getUserById($id) {
        $stmt = $this->pdo->prepare("SELECT name, email FROM users WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch(PDO::FETCH_ASSOC); // Returns raw data, NO HTML!
    }
}
?>

6. Step 2: The View

We create a View file that *only* contains HTML. It expects a $userData variable to magically exist.

views/profile.php

html
12345678
<!DOCTYPE html>
<html>
<body>
    <h1>User Profile</h1>
    <p>Name: <?php echo htmlspecialchars($userData[&#039;name']); ?></p>
    <p>Email: <?php echo htmlspecialchars($userData[&#039;email']); ?></p>
</body>
</html>

7. Step 3: The Controller

The Controller ties it all together.

controllers/UserController.php

php
1234567891011121314151617181920
<?php
require &#039;models/UserModel.php';

class UserController {
    private $db;

    public function __construct($db_connection) {
        $this->db = $db_connection;
    }

    public function showProfile($user_id) {
        // 1. Ask the Model for data
        $model = new UserModel($this->db);
        $userData = $model->getUserById($user_id);
        
        // 2. Load the View (which will now have access to the $userData variable)
        require &#039;views/profile.php';
    }
}
?>

8. Backend Workflow: The Router Connects to the Controller

In the previous chapter, our router echoed HTML. Now, the router triggers a Controller.

index.php (The Router)

php
1234567891011121314
<?php
require &#039;db.php'; // Get $pdo connection
require &#039;controllers/UserController.php';

$uri = $_SERVER[&#039;REQUEST_URI'];

if (preg_match(&#039;/^\/user\/([0-9]+)$/', $uri, $matches)) {
    $user_id = $matches[1];
    
    // Trigger the Controller!
    $controller = new UserController($pdo);
    $controller->showProfile($user_id);
}
?>

*Flow:* URL typed -> Router intercepts -> Triggers Controller -> Controller asks Model for data -> Controller gives data to View -> View displays HTML to user.

9. Best Practices

  • Fat Models, Skinny Controllers: A common industry rule. The Controller should only be a few lines long (route traffic, pass data). If you have 100 lines of complex math or data manipulation, it belongs in the Model.

10. Common Mistakes

  • Putting SQL in the View: Beginners often open an HTML file and immediately write $pdo->query(...) at the top. This violates MVC. If a front-end developer needs to change the CSS, they might accidentally break the database query. Keep SQL strictly in the Model.

11. Exercises

  1. 1. Explain the "Restaurant Analogy" of MVC to describe how data flows from the database to the user's screen.

12. Coding Challenges

  • Challenge: Create a conceptual directory structure for a blog. List out the names of the files you would create in the /models, /views, and /controllers folders to handle displaying a single blog post.

13. MCQs with Answers

Question 1

In the MVC design pattern, which component is strictly responsible for interacting with the MySQL database?

Question 2

What is the primary benefit of using the MVC architecture in backend development?

14. Interview Questions

  • Q: Define the MVC architecture. Walk me through the lifecycle of a request entering a Router, passing through the MVC layers, and returning an HTTP response.
  • Q: What does the phrase "Fat Models, Skinny Controllers" mean in software architecture?

15. FAQs

Q: Do I have to build an MVC framework from scratch for every project? A: Never! Building it from scratch is a learning exercise. In the real world, you use a framework like Laravel or Symfony. They provide a massive, pre-built, highly secure MVC structure so you can just focus on writing your specific app logic.

16. Summary

In Chapter 14, we cured "Spaghetti Code." By organizing our application into the Model-View-Controller architecture, we achieved Separation of Concerns. The Model handles the data, the View handles the HTML, and the Controller acts as the traffic coordinator. This professional structure is the exact architectural foundation used by enterprise PHP frameworks like Laravel, ensuring our code remains clean and maintainable as the project grows.

17. Next Chapter Recommendation

Our application is beautifully structured, but is it secure? Proceed to Chapter 15: PHP Security Best Practices to audit our defenses.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·