Статья

📘 Глава 16. Основы MVC без фреймворка

Сейчас мы сделаем следующий шаг — введём структуру MVC (Model-View-Controller) на чистом PHP. Это основа большинства современных веб-приложений.


🎯 Что такое MVC?

MVC — это архитектурный шаблон:

  • Model — взаимодействует с базой данных

  • View — отвечает за отображение (HTML)

  • Controller — обрабатывает логику (формы, действия и т.п.)


📁 Структура проекта

guestbook/
├── app/
│   ├── Controllers/
│   │   └── MessageController.php
│   ├── Models/
│   │   └── Message.php
│   └── Views/
│       ├── layout.php
│       └── messages.php
├── core/
│   └── Database.php
├── public/
│   └── index.php

🔧 1. core/Database.php (наш класс из предыдущей главы)

<?php

class Database {
    private PDO $pdo;

    public function __construct($host, $dbname, $user, $pass) {
        $dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
        $this->pdo = new PDO($dsn, $user, $pass);
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    public function query($sql, $params = []) {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        return $stmt;
    }

    public function fetchAll($sql, $params = []) {
        return $this->query($sql, $params)->fetchAll(PDO::FETCH_ASSOC);
    }

    public function execute($sql, $params = []) {
        return $this->query($sql, $params)->rowCount();
    }
}

📄 2. app/Models/Message.php

<?php

require_once __DIR__ . '/../../core/Database.php';

class Message {
    private Database $db;

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

    public function getAll() {
        return $this->db->fetchAll("SELECT * FROM messages ORDER BY created_at DESC");
    }

    public function save($author, $text) {
        return $this->db->execute(
            "INSERT INTO messages (author, text) VALUES (?, ?)",
            [$author, $text]
        );
    }
}

🧠 3. app/Controllers/MessageController.php

<?php

require_once __DIR__ . '/../Models/Message.php';

class MessageController {
    private Message $model;

    public function __construct(Message $model) {
        $this->model = $model;
    }

    public function index() {
        $messages = $this->model->getAll();
        require __DIR__ . '/../Views/messages.php';
    }

    public function store() {
        $author = trim($_POST["author"] ?? '');
        $text = trim($_POST["text"] ?? '');

        if ($author && $text) {
            $this->model->save($author, $text);
            header("Location: /");
            exit;
        } else {
            echo "Both fields are required.";
        }
    }
}

🖼 4. app/Views/layout.php

<!DOCTYPE html>
<html>
<head>
    <title>Guestbook</title>
</head>
<body>
    <h1>Guestbook</h1>
    <?= $content ?>
</body>
</html>

🖼 5. app/Views/messages.php

<?php ob_start(); ?>

<form method="post" action="/?action=store">
    <input type="text" name="author" placeholder="Your name"><br>
    <textarea name="text" placeholder="Your message"></textarea><br>
    <button type="submit">Send</button>
</form>

<hr>

<?php foreach ($messages as $message): ?>
    <p><strong><?= htmlspecialchars($message["author"]) ?>:</strong> <?= htmlspecialchars($message["text"]) ?></p>
<?php endforeach; ?>

<?php
$content = ob_get_clean();
require __DIR__ . '/layout.php';

🚪 6. public/index.php — точка входа

<?php

require_once __DIR__ . '/../core/Database.php';
require_once __DIR__ . '/../app/Models/Message.php';
require_once __DIR__ . '/../app/Controllers/MessageController.php';

$db = new Database("localhost", "guestbook", "root", "password");
$messageModel = new Message($db);
$controller = new MessageController($messageModel);

$action = $_GET["action"] ?? "index";

if ($action === "store" && $_SERVER["REQUEST_METHOD"] === "POST") {
    $controller->store();
} else {
    $controller->index();
}

✅ Что ты изучил

  • Что такое MVC и зачем он нужен

  • Как разделить код на контроллер, модель и представление

  • Как делать маршрутизацию вручную (через action)


В следующей главе — автоматическая маршрутизация и упрощение структуры, а потом перейдём к ООП в PHP.

PHP
Для ответа вы можете авторизоваться