PHP часто используют вместе с MySQL: формы, заявки, каталоги, WordPress, админки, личные кабинеты. Но начинать нужно не со старых mysql_* функций и не со склейки SQL-строк. В этом уроке подключимся к MySQL через PDO, прочитаем список задач и добавим новую запись через prepared statement
Главная цель: увидеть безопасный базовый путь PDO -> prepare -> execute, а не копировать уязвимый код из старых примеров
Что получится в конце
У нас будет таблица tasks:
create table tasks (
id int auto_increment primary key,
title varchar(255) not null,
done tinyint(1) not null default 0
);
PHP-страница покажет список задач и позволит добавить новую через POST-форму
Подготовка базы
Создайте базу php_lessons и таблицу:
create database php_lessons character set utf8mb4 collate utf8mb4_unicode_ci;
use php_lessons;
create table tasks (
id int auto_increment primary key,
title varchar(255) not null,
done tinyint(1) not null default 0
);
insert into tasks (title) values ('Разобрать PDO в PHP');
Пользователь, пароль и хост зависят от вашей локальной среды: XAMPP, Open Server, Docker или отдельный MySQL
Подключение через PDO
Создайте index.php:
<?php
$pdo = new PDO(
'mysql:host=127.0.0.1;dbname=php_lessons;charset=utf8mb4',
'root',
'',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
ERRMODE_EXCEPTION нужен, чтобы ошибки базы не превращались в молчание. FETCH_ASSOC делает строки удобными ассоциативными массивами
На реальном сервере пароль нельзя хранить прямо в публичном файле. Для учебного локального проекта это допустимое упрощение, но привычку выносить настройки в конфиг лучше сформировать позже
Читаем задачи
Добавьте:
$statement = $pdo->query('select id, title, done from tasks order by id desc');
$tasks = $statement->fetchAll();
Теперь выведите список:
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>PHP и MySQL</title>
</head>
<body>
<h1>Задачи</h1>
<ul>
<?php foreach ($tasks as $task): ?>
<li>
<?= htmlspecialchars($task['title']) ?>
<?= $task['done'] ? 'готово' : 'в работе' ?>
</li>
<?php endforeach; ?>
</ul>
</body>
</html>
Если список появился, SELECT работает
Добавляем форму
Перед списком:
<form method="post">
<input name="title" placeholder="Новая задача">
<button type="submit">Добавить</button>
</form>
В начало файла после подключения добавьте обработку POST:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = trim($_POST['title'] ?? '');
if ($title !== '') {
$statement = $pdo->prepare('insert into tasks (title) values (:title)');
$statement->execute([
'title' => $title,
]);
header('Location: /');
exit;
}
}
header('Location: /') после успешного добавления защищает от повторной отправки формы при обновлении страницы
Почему prepare лучше склейки SQL
Плохой путь:
$sql = "insert into tasks (title) values ('$title')";
$pdo->exec($sql);
Если пользователь отправит кавычки или SQL-фрагмент, запрос может сломаться или стать уязвимым
Правильный путь:
$statement = $pdo->prepare('insert into tasks (title) values (:title)');
$statement->execute(['title' => $title]);
SQL и данные передаются отдельно. Это базовая защита от SQL-инъекций
Частые ошибки
could not find driver. Не включено расширение PDO MySQL. Проверьте phpinfo() и настройки вашей сборки PHP
Access denied for user. Неверный пользователь, пароль или права в MySQL
Unknown database. База не создана или имя в DSN написано иначе
Headers already sent. header() вызван после вывода HTML. Обработка POST и redirect должны быть до вывода страницы
Что может быть еще интересно по этой теме
PDO заменяет MySQL? Нет. PDO — интерфейс PHP для работы с базой. MySQL остается сервером базы данных
Prepared statements нужны только для INSERT? Нет. Они нужны для любых запросов с пользовательскими данными: SELECT, UPDATE, DELETE
htmlspecialchars защищает базу? Нет. Он нужен для HTML-вывода. Для SQL используйте prepared statements
Стоит ли начинать с ORM? Новичку полезно сначала понять PDO и SQL. ORM можно добавить позже, когда база уже не выглядит магией
Что открыть дальше
- Формы в PHP: GET, POST и первая обработка — база для POST-обработки.
- Массивы в PHP: обычные, ассоциативные и foreach — строки из PDO удобно выводить как массивы.
- Composer в PHP: установка пакетов без ручного копирования — следующий шаг к современным PHP-проектам.
- Ошибки PHP: белый экран, error log и display_errors — пригодится при ошибках подключения.



