Статья
📘 Глава 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.
37