4.1 · Understanding the MVC pattern

Level 4 · Frameworks & API

4.1Understanding the MVC pattern

Goal: Understand the MVC pattern (separating data, display, coordination) and its flow — the foundation of web frameworks, so you can use them wisely and structure your applications cleanly.
Estimated time: 11 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • MVC = 3 separate responsibilities: the Model handles data and business logic, the View renders HTML, the Controller orchestrates (request → model → view).
  • Typical flow: request → routing to the right controller → controller calls the model → model returns the data → controller picks the view.
  • Riad's reflex: thin controllers, rich models — never any SQL queries in views, never any business logic in the display.

Running case — Riad tidies up his catalogue in Constantine

Riad, web developer in Constantine, maintains the catalogue of a local shop: his file mixes SQL queries, price calculations and HTML, and every change breaks something else. He decides to tidy up: a model that fetches products by category, a controller that orchestrates the "products" page, a view that displays the list it receives. When the client asks for a new display, Riad only touches the view; when the pricing rule changes, he only touches the model. First milestone of the thread: from messy PHP to architected PHP.

This same case returns in the lesson, the diagram, the script and the 48h challenge — and continues in 4.2, 4.3, 4.4 and 4.5.

1. The three responsibilities

The MVC (Model-View-Controller) pattern splits the application into three layers. The Model handles DATA and BUSINESS LOGIC: database access, entities (Product, User), rules (discounted price, unique e-mail) — independently of the display. The View handles DISPLAY: HTML with minimal insertions (showing a variable, looping over a list), with no business logic or database access. The Controller is the LINK: it receives the request, calls the model, prepares the data, then picks the view. Like Riad, aim for "thin" controllers and "rich" models.

The golden rule: every piece of code has ONE obvious place. Data or business rule? Model. HTML? View. Request → data → display coordination? Controller. This clarity eliminates "spaghetti code" where everything is mixed in a single file.

2. The request flow & the benefits

The typical flow: (1) the user requests a URL; (2) routing directs to the right CONTROLLER and its method; (3) the controller calls the MODEL (e.g. fetching the products); (4) the controller passes the data to the VIEW; (5) the view generates the HTML. Riad follows this path for every page instead of doing everything in a single script.

The benefits: clarity (you know where to find what), maintainability (change the view without touching the data, and vice versa), reuse and testing (the same models serve an HTML page or a JSON API), collaboration (everyone works on their own layer). It is the DOMINANT pattern of frameworks (Laravel, Symfony): Models, Controllers, views/templates folders plus routing — understanding it BEFORE a framework means using it wisely instead of imitating it blindly.

Common misinterpretation: "MVC is just putting my files into three folders." No. Moving mixed code into three folders without separating responsibilities changes nothing: if the view runs SQL queries and the controller computes prices, it is still spaghetti — with labels. MVC is a discipline of distribution (data to the model, display to the view, coordination to the controller), not cosmetic tidying.
The MVC flow of a request Request → controller → model → view Request + routing URL directedto the right controllerController Orchestrates:calls the modelModel Data + business logic(database, rules)View Renders HTML withthe received data
Request → controller → model → view
Text version of the diagram (SEO / screen readers / translation): 1) Riad receives a request: routing directs it to the right controller. 2) The controller calls the model to fetch or process the data. 3) The model applies the business rules and returns ready-to-use data. 4) The controller picks the view and passes it the data. Lesson: separating data, display and coordination makes the application clear, maintainable and testable.

🔎 Concrete example — 🔎 Concrete example — The product list in MVC

Riad's breakdown for the catalogue page:

Model        → Produit::recupererParCategorie($cat) // SQL + rules here
Controller   → $produits = Produit::recupererParCategorie($cat);
               afficher('liste', ['produits' => $produits]);
View         → foreach ($produits as $p) { show $p['nom'], $p['prix'] }
Rule         → change the display = touch the view only

Reading: three blocks, three roles, one direction of travel.

Lesson: the view receives ready-made data; it does not build it.

Section vocabulary

MVC (Model-View-Controller)
Architecture pattern separating the application into three responsibilities: Model (data/business logic), View (display), Controller (coordination). The foundation of web frameworks.

Simple example: Riad tidies his catalogue: model for products, view for HTML, controller to orchestrate.

What it is not: a single script mixing SQL, calculations and HTML.

Reflex: for each line of code, ask: data, display or coordination?

Model
Handles DATA and BUSINESS LOGIC: database access, entities, rules — independently of the display.

Simple example: Riad's Product model fetches products and computes the discounted price.

What it is not: an SQL query written inside a display template.

Reflex: every business rule lives in the model, testable without HTML.

View
Handles DISPLAY: the HTML, what the user sees; receives prepared data and presents it.

Simple example: Riad's list view loops over the received products and displays them escaped.

What it is not: a template that queries the database or applies discounts.

Reflex: "dumb" view: display, loop, simple condition — nothing more.

Controller
Is the LINK: receives the request, calls the model, picks the view with the data; it orchestrates, thin and readable.

Simple example: Riad's catalogue controller fetches the products then renders the list view.

What it is not: a 300-line controller doing SQL + calculations + HTML.

Reflex: thin controller: coordinate, delegate, render.

Routing / MVC flow
Routing directs the request to the right controller; flow: request → routing → controller → model → view.

Simple example: Riad's /produits URL reaches the catalogue controller, index method.

What it is not: one file per URL with no central coordination.

Reflex: follow the flow on every debug: where does the chain break?

In practice — In practice — Understand and apply MVC

  1. Identify the three responsibilities: Model (data/logic), View (HTML display), Controller (coordination) — and why to separate them.
  2. Follow a request's flow: request → routing → controller → model (data) → view (display).
  3. On a small example (Riad's product list), distribute the code: model that fetches, controller that calls, view that displays.
  4. Observe the benefits: change the view without touching the model, and vice versa — clarity, maintainability, testing.
You understand the MVC pattern (separating data, display, coordination) and its flow — the foundation of frameworks, which structures your applications cleanly.

Ready-to-say script — explain your MVC tidy-up (30 s)

"This is Riad: I moved the queries and pricing rules into the model, the HTML into the view, and the controller only orchestrates — request, model, view. Result: I change the display without touching the data, and I can test the logic without a browser."

Say it in a code review; show the three files side by side.

Copy-paste template — mini-MVC in plain PHP (tested code)

prepare('SELECT nom, prix FROM produits WHERE categorie = :cat');
        $stmt->execute(['cat' => $cat]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    public static function prixRemise(float $prix, float $taux): float {
        return round($prix * (1 - $taux), 2);
    }
}

// --- Controller: thin, it orchestrates ---
function indexCatalogue(PDO $pdo, string $cat): void {
    $produits = Produit::recupererParCategorie($pdo, $cat);
    afficherVue('liste', ['produits' => $produits]); // picks the view
}

// --- View: dumb, it displays (data already prepared, escaped) ---
function afficherVue(string $nom, array $vars): void {
    $produits = $vars['produits'];
    foreach ($produits as $p) {
        echo '
  • ' . htmlspecialchars($p['nom']) . ' — ' . htmlspecialchars((string) $p['prix']) . ' DA
  • '; } }

    Small personal script

    A light separation (3 functions or 3 files) is enough, but keep the discipline: no queries in the display.

    Team project

    Like Riad: models/, controllers/, views/ folders — everyone knows where to work without conflicts.

    Same models, two outputs

    Reuse the model for an HTML page and for a JSON API: only the view changes.

    Before a framework

    Practise this breakdown in plain PHP: Laravel and Symfony will feel obvious instead of magical.

    Caution: A good breakdown excuses no vulnerability: prepared statements in models and escaping in views (see level 3), even when the code is well organized. Teaching content, examples with fictitious data.

    ✓ Best practices

    • Separate the 3 roles: data, display, coordination.
    • Aim for thin controllers and rich models.
    • Understand MVC before tackling a framework.

    ✗ Common pitfalls

    • Putting SQL queries in views.
    • Putting business logic in controllers.
    • Reproducing spaghetti INSIDE the framework.

    Key takeaways

    • MVC = 3 responsibilities: MODEL (data + business logic), VIEW (HTML display), CONTROLLER (request → model → view coordination).
    • FLOW: request → ROUTING (right controller) → CONTROLLER → MODEL (data) → VIEW (display).
    • BENEFITS: clarity, maintainability, reuse/testing, collaboration.
    • Understanding MVC BEFORE a framework = using it wisely. Moving from messy PHP to ARCHITECTED PHP.

    48h challenge — apply it tomorrow

    Take 1 mixed page and split it into model + controller + view: the model fetches, the controller orchestrates, the view displays.

    Section exit checklist
    • I can name the 3 layers and their roles.
    • I can follow a request's flow.
    • I have split 1 page into clean MVC.
    Self-rating 1-5: are my views free of business logic?do my controllers stay thin and readable?

    Frequently asked questions

    Why understand MVC before learning a framework directly?

    Because frameworks impose an MVC structure (Models, Controllers, views folders, routing): without understanding the WHY, you imitate tutorials without knowing where to put what, you mix responsibilities INSIDE the framework, and you are lost as soon as you leave the tutorial's case. With MVC understood, the structure becomes obvious, you keep the separation (benefits preserved), you debug by following the flow, and the concepts transfer (Laravel, Symfony, and beyond).

    How to distribute the code concretely — and which mistakes to avoid?

    Model: database access (CRUD), entities, business rules — independent of display. View: HTML + minimal insertions of already-prepared data (loop, escaped display), never SQL or rules. Controller: receives the request, calls the model, picks the view — it orchestrates, thin. Classic mistakes: queries in views, business logic in controllers, 300-line controllers. "Dumb" views, "rich" models, "thin" controllers.

    Check your understanding

    Where do business logic and database access belong?

    Additional resources (optional, to go further)

    Level 4 examFresh, harder questions to test what you've learned