php · level 3 · unit 6 · lesson 4
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
splits an app into data, display and decisions.
Most PHP frameworks follow MVC. The holds data and its rules: finding pets, refusing bad ones. The turns data into HTML and escapes every value. The sits between them: it reads the request, asks the model, then hands the answer to a view.
Each part has one job. You can change how pets look without touching how they are stored, and test the rules with no HTML at all. In a full app, the router from the last lesson picks which controller method runs.
<?php
class PetModel {
public function kindOf(string $name): ?string { return ["rex" => "dog", "tom" => "cat"][$name] ?? null; }
}
function petView(string $name, string $kind): string {
return "<h1>" . htmlspecialchars("$name the $kind", ENT_QUOTES) . "</h1>";
}
class PetController {
public function __construct(private PetModel $model) {}
public function show(array $query): string {
$name = $query["name"] ?? "";
return petView($name, $this->model->kindOf($name) ?? "mystery pet");
}
}
$_GET = ["name" => "rex"];
echo (new PetController(new PetModel()))->show($_GET) . "\n"; The model never writes HTML and the view never touches data storage, so each can change on its own.
guess first
Someone visits with a sneaky name. What will this show?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
<?php
class PetModel {
public function kindOf(string $name): ?string { return ["rex" => "dog", "tom" => "cat"][$name] ?? null; }
}
function petView(string $name, string $kind): string {
return "<h1>" . htmlspecialchars("$name the $kind", ENT_QUOTES) . "</h1>";
}
class PetController {
public function __construct(private PetModel $model) {}
public function show(array $query): string {
$name = $query["name"] ?? "";
return petView($name, $this->model->kindOf($name) ?? "mystery pet");
}
}
$_GET = ["name" => "<i>bob</i>"];
echo (new PetController(new PetModel()))->show($_GET) . "\n";
your turn
Your turn. Finish the café's menu page.
Add a dish of your own to the model. Then escape each dish in the view, and make the controller ask the model for its dishes.
fix it
The reviews page lets raw HTML through. Fix it.
- There is a view that escapes properly. Is it ever called?
- The controller builds its own HTML on line 11 and skips the view, so nothing gets escaped. Building HTML is the view's job.
- Change line 11 to
return reviewView($this->model->latest());, then run it.
nailed it
your app has a model, view and controller. :D
- The model holds data and rules, with no HTML at all.
- The view turns data into HTML and escapes every value.
- The controller reads the request and joins model and view.
new words in your collection
- MVC
- model
- view
- controller
This lesson isn’t saved. A free account remembers every lesson you finish.