Урок 18
Создаём функции для работы с данными
25 минЗачем нужны функции для работы с данными?
Вместо того чтобы писать SQL-запросы в каждом файле, мы создадим функции:
getAllPosts()— получить все постыgetPostById($id)— получить пост по IDgetUserById($id)— получить пользователя
Это делает код чище и проще в поддержке.
Создаём файл с функциями
Создайте файл public/includes/database.php:
<?php
declare(strict_types=1);
/**
* Функции для работы с базой данных
*
* Используется глобальная переменная $pdo из config.php
*/
/**
* Получить все посты
*
* @param int $limit Максимальное количество постов
* @return array Массив постов
*/
function getAllPosts(int $limit = 10): array {
global $pdo;
$stmt = $pdo->prepare("
SELECT posts.*, users.username as author_name
FROM posts
JOIN users ON posts.user_id = users.id
ORDER BY posts.created_at DESC
LIMIT ?
");
$stmt->execute([$limit]);
return $stmt->fetchAll();
}
/**
* Получить пост по ID
*
* @param int $id ID поста
* @return array|false Массив с данными поста или false
*/
function getPostById(int $id): array|false {
global $pdo;
$stmt = $pdo->prepare("
SELECT posts.*, users.username as author_name
FROM posts
JOIN users ON posts.user_id = users.id
WHERE posts.id = ?
");
$stmt->execute([$id]);
return $stmt->fetch();
}
/**
* Создать новый пост
*
* @param int $userId ID автора
* @param string $title Заголовок
* @param string $content Содержимое
* @return int ID созданного поста
*/
function createPost(int $userId, string $title, string $content): int {
global $pdo;
$stmt = $pdo->prepare("
INSERT INTO posts (user_id, title, content)
VALUES (?, ?, ?)
");
$stmt->execute([$userId, $title, $content]);
return $pdo->lastInsertId();
}
/**
* Обновить пост
*
* @param int $id ID поста
* @param string $title Новый заголовок
* @param string $content Новое содержимое
* @return int Количество обновлённых записей
*/
function updatePost(int $id, string $title, string $content): int {
global $pdo;
$stmt = $pdo->prepare("
UPDATE posts
SET title = ?, content = ?
WHERE id = ?
");
$stmt->execute([$title, $content, $id]);
return $stmt->rowCount();
}
/**
* Удалить пост
*
* @param int $id ID поста
* @return int Количество удалённых записей
*/
function deletePost(int $id): int {
global $pdo;
$stmt = $pdo->prepare("DELETE FROM posts WHERE id = ?");
$stmt->execute([$id]);
return $stmt->rowCount();
}
/**
* Получить пользователя по ID
*/
function getUserById(int $id): array|false {
global $pdo;
$stmt = $pdo->prepare("SELECT id, username, email, created_at FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}
/**
* Получить пользователя по username или email
*/
function getUserByLogin(string $login): array|false {
global $pdo;
$stmt = $pdo->prepare("
SELECT * FROM users
WHERE username = ? OR email = ?
");
$stmt->execute([$login, $login]);
return $stmt->fetch();
}
/**
* Создать пользователя
*/
function createUser(string $username, string $email, string $password): int {
global $pdo;
// Хешируем пароль!
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("
INSERT INTO users (username, email, password)
VALUES (?, ?, ?)
");
$stmt->execute([$username, $email, $hashedPassword]);
return $pdo->lastInsertId();
}
/**
* Проверить пароль пользователя
*/
function verifyPassword(array $user, string $password): bool {
return password_verify($password, $user["password"]);
}
/**
* Получить количество постов
*/
function getPostsCount(): int {
global $pdo;
$stmt = $pdo->query("SELECT COUNT(*) as count FROM posts");
$result = $stmt->fetch();
return $result["count"];
}
?>
Подключаем в config.php
Добавьте в конец config.php:
// Подключаем функции для работы с БД
require_once __DIR__ . "/database.php";
Обновляем главную страницу
Теперь перепишем public/index.php с использованием реальных данных:
<?php
require_once "includes/config.php";
$page_title = "Главная — $site_name";
// Получаем посты из базы данных!
$posts = getAllPosts(10);
include "includes/header.php";
?>
<h2>Добро пожаловать в блог!</h2>
<p><?= escape($site_description) ?></p>
<h3>Последние публикации</h3>
<?php if (empty($posts)): ?>
<p>Пока нет ни одной публикации.</p>
<?php else: ?>
<?php foreach ($posts as $post): ?>
<article style="background: #f9f9f9; padding: 20px; margin: 15px 0; border-radius: 8px;">
<h4 style="margin-bottom: 10px;">
<a href="post.php?id=<?= $post["id"] ?>" style="color: #333; text-decoration: none;">
<?= escape($post["title"]) ?>
</a>
</h4>
<small style="color: #888;">
<?= formatDate($post["created_at"]) ?> •
Автор: <?= escape($post["author_name"]) ?>
</small>
<p style="margin-top: 10px;">
<?= truncate(escape($post["content"]), 150) ?>
</p>
<a href="post.php?id=<?= $post["id"] ?>" style="color: #F36049;">Читать далее →</a>
</article>
<?php endforeach; ?>
<?php endif; ?>
<?php include "includes/footer.php"; ?>
Страница отдельного поста
Создайте public/post.php:
<?php
require_once "includes/config.php";
// Получаем ID из URL
$id = isset($_GET["id"]) ? (int)$_GET["id"] : 0;
// Получаем пост
$post = getPostById($id);
// Если пост не найден
if (!$post) {
http_response_code(404);
$page_title = "Пост не найден — $site_name";
include "includes/header.php";
echo "<h2>Пост не найден</h2>";
echo "<p>Запрашиваемая публикация не существует.</p>";
echo '<p><a href="index.php">← Вернуться на главную</a></p>';
include "includes/footer.php";
exit;
}
$page_title = escape($post["title"]) . " — $site_name";
include "includes/header.php";
?>
<article>
<h2><?= escape($post["title"]) ?></h2>
<div style="color: #888; margin-bottom: 20px;">
<?= formatDate($post["created_at"]) ?> •
Автор: <?= escape($post["author_name"]) ?>
</div>
<div style="line-height: 1.8;">
<?= nl2br(escape($post["content"])) ?>
</div>
<p style="margin-top: 30px;">
<a href="index.php" style="color: #F36049;">← Вернуться к списку постов</a>
</p>
</article>
<?php include "includes/footer.php"; ?>
Проверяем
- Откройте
http://localhost:8080— должны увидеть посты из базы данных - Кликните на заголовок поста — откроется страница поста
- Попробуйте несуществующий ID:
http://localhost:8080/post.php?id=999— увидите "Пост не найден"
Удаляем тестовый файл
Файл test_db.php больше не нужен — можете удалить его.
Модуль 3 завершён!
Вы научились:
✅ Понимать что такое база данных
✅ Работать с phpMyAdmin
✅ Писать SQL-запросы
✅ Подключать PHP к MySQL через PDO
✅ Создавать функции для работы с данными
Теперь у вас настоящий блог с данными из базы!
В следующем модуле добавим авторизацию пользователей.
Вы научились:
✅ Понимать что такое база данных
✅ Работать с phpMyAdmin
✅ Писать SQL-запросы
✅ Подключать PHP к MySQL через PDO
✅ Создавать функции для работы с данными
Теперь у вас настоящий блог с данными из базы!
В следующем модуле добавим авторизацию пользователей.