Architectural Patterns in PHP: From MVC to CQRS

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Architecture Solves Everything (And Your Coffee Will No Longer Get Cold)

\n

Imagine you are building a house. You can pile up bricks haphazardly, stick them together with gum, and hope it lasts until winter. Or you can design the foundation, walls, and roof so that the house survives both a hurricane and an invasion of relatives. In the world of PHP, it's exactly the same. Architectural patterns are those very blueprints that turn your code from "it works — and that's fine" into "it works, scales, and doesn't make you want to drink iodine."

\n

When I started coding in PHP, my projects were monolithic monsters. In one index.php file, SQL queries, HTML markup, and business logic all coexisted. This worked exactly until the client asked to add a new feature. Then hell broke loose. Today, I will show you how to avoid this hell. We will break down the key architectural patterns in PHP — from classics to modern approaches. Let's go!

\n\n

MVC (Model-View-Controller): The Grandfather of All Patterns

\n

If you've written code in Laravel, Symfony, or Yii2, you've already encountered MVC. This is the basic architectural pattern in PHP that divides the application into three parts:

\n
    \n
  • Model — data and business logic (working with the database, validation, calculations).
  • \n
  • View — display (HTML, templates, JSON).
  • \n
  • Controller — the glue: receives a request, calls the Model, and passes data to the View.
  • \n
\n

MVC solves the main problem — separation of concerns. No more SQL in HTML. The code becomes readable, testable, and maintainable.

\n\n

MVC Example in Pure PHP

\n
// Model: User.php\nclass User {\n    public function find(int $id): ?array {\n        $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');\n        $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');\n        $stmt->execute([$id]);\n        return $stmt->fetch() ?: null;\n    }\n}\n\n// Controller: UserController.php\nclass UserController {\n    public function show(int $id): void {\n        $userModel = new User();\n        $user = $userModel->find($id);\n        if (!$user) {\n            http_response_code(404);\n            echo 'User not found';\n            return;\n        }\n        // Pass data to the View\n        require 'views/user.php';\n    }\n}\n\n// View: views/user.php\n<h1><?= htmlspecialchars($user['name']) ?></h1>\n<p>Email: <?= htmlspecialchars($user['email']) ?></p>
\n

When to use: for medium-complexity web applications. If you have a simple blog or an online store — MVC is your choice. But be careful: if controllers become fat (Fat Controllers), the pattern loses its meaning.

\n\n

Active Record: Simplicity and Speed

\n

The Active Record pattern is when an object simultaneously represents a database row and business logic. Remember Laravel Eloquent or Yii2 ActiveRecord? That's it. Each model is both a database query and validation rules and relationships.

\n\n

Active Record Example (Eloquent style)

\n
class User extends ActiveRecord {\n    // Properties correspond to table columns\n    public int $id;\n    public string $name;\n    public string $email;\n\n    public function save(): bool {\n        // INSERT/UPDATE logic\n        if ($this->id) {\n            // UPDATE\n        } else {\n            // INSERT\n        }\n        return true;\n    }\n\n    public static function find(int $id): ?self {\n        // SELECT * FROM users WHERE id = $id\n    }\n}\n\n// Usage\n$user = new User();\n$user->name = 'Ivan';\n$user->email = 'ivan@example.com';\n$user->save(); // Simple and clear
\n

Pros: quick to write, intuitively understandable for beginners. Cons: violates the Single Responsibility Principle (from SOLID). The model knows about both the data and how to save it. For complex pro

Blogs

Book Recommendations