Documentation · Chapter 02

Separate responsibilities
with MVC.

MVC does not mean creating three folders for every page. It separates decisions, data, and presentation.

The controller is not the whole application.

MModel

Represents data and business rules. It does not decide button color.

VView

Presents information. It should not execute an SQL query.

CController

Receives the use case, calls what is needed, and chooses the response.

Example: display a product.

phpaml — zsh
'GET /products/{id}' => [ProductController::class, 'show']
phpaml — zsh
public function show(Request $request): Response
{
    $product = $this->products->find((int) $request->attribute('id'));

    if ($product === null) {
        return Response::html('<h1>Not found</h1>', 404);
    }

    return $this->view('products/show.php', ['product' => $product]);
}

The route knows the address and action. The controller converts the identifier, asks the repository for the product, handles absence, then chooses a view. The view receives a product ready to display.

Recognize a misplaced responsibility.

SQL inside a view

The view then knows storage details and becomes hard to test.

HTML inside a model

The model can no longer serve an API or another presentation.

Everything in the controller

Business rules become long, duplicated, and hard to reuse.

CHECK YOUR UNDERSTANDING

Who should verify that a discount is allowed: the view or business domain?

Show the answer

The business domain, usually in a model or service. The view only presents the result.

SUMMARY

What to remember

  • The model owns data and business rules.
  • The view presents.
  • The controller coordinates.
  • Good separation reuses the same logic for HTML or JSON.