База данных — это сердце любого динамического сайта. Без неё невозможно представить интернет-магазин, блог или социальную сеть. В этой статье мы разберём, как подружить PHP с MySQL: от простого подключения до защиты от хакерских атак. Обещаю, будет понятно и без лишней теории.

Digital-студия WNDER

Почему MySQL и PHP — классическая связка?

PHP и MySQL идут рука об руку уже много лет. PHP — это язык, который выполняется на сервере и генерирует HTML-страницы. MySQL — это система управления базами данных (СУБД), где хранятся все данные: пользователи, товары, комментарии. Вместе они позволяют создавать сайты, которые меняются в зависимости от запроса пользователя.

Представьте ресторан. PHP — это официант, который принимает заказы и приносит блюда. MySQL — это кладовая, где хранятся продукты. Официант (PHP) идёт в кладовую (MySQL), берёт нужные ингредиенты (данные) и готовит блюдо (страницу). Без кладовой официант бесполезен, а без официанта кладовая так и останется закрытой.

Связка популярна потому, что она бесплатна, проста в установке и имеет огромное сообщество. Если вы только начинаете, это лучший выбор.

Как подключиться к MySQL из PHP: три способа

Есть три основных расширения для работы с MySQL в PHP: mysql (устаревшее и удалённое в PHP 7), mysqli (улучшенное, поддерживает объектно-ориентированный и процедурный стили) и PDO (универсальное, работает с разными базами). Мы будем использовать PDO, потому что он безопаснее и переносим. Но сначала покажу, как выглядит подключение через mysqli, чтобы вы понимали разницу.

Пример подключения через mysqli (объектно-ориентированный стиль):

connect_error) {
    die("Ошибка подключения: " . $conn->connect_error);
}
echo "Подключение успешно";
?>

А теперь то же самое, но через PDO:

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Подключение успешно";
} catch(PDOException $e) {
    echo "Ошибка подключения: " . $e->getMessage();
}
?>

Согласитесь, PDO выглядит аккуратнее и сразу использует try-catch для обработки ошибок. Это современный подход.

Правило: Всегда используйте PDO или mysqli с подготовленными выражениями. Никогда не вставляйте данные пользователя в SQL-запрос напрямую — это прямая дорога к SQL-инъекциям.

Выполнение запросов: SELECT, INSERT, UPDATE, DELETE

После подключения можно выполнять SQL-запросы. Рассмотрим четыре основные операции на примере таблицы users с полями id, name, email.

SELECT — выборка данных. Допустим, мы хотим получить всех пользователей:

prepare("SELECT id, name, email FROM users");
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($result as $row) {
    echo $row['name'] . " — " . $row['email'] . "
"; } ?>

INSERT — добавление новой записи. Используем именованные параметры для безопасности:

prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);

$name = "Иван";
$email = "ivan@example.com";
$stmt->execute();

echo "Новый пользователь добавлен";
?>

UPDATE — обновление существующей записи. Например, меняем email пользователя с id=1:

prepare("UPDATE users SET email = :email WHERE id = :id");
$stmt->bindParam(':email', $newEmail);
$stmt->bindParam(':id', $id);

$newEmail = "new@example.com";
$id = 1;
$stmt->execute();

echo "Email обновлён";
?>

DELETE — удаление записи. Будьте осторожны, обратной операции нет:

prepare("DELETE FROM users WHERE id = :id");
$stmt->bindParam(':id', $id);
$id = 2;
$stmt->execute();

echo "Пользователь удалён";
?>

Как видите, подготовленные запросы (prepared statements) используются везде. Это не только безопасно, но и удобно: вы один раз готовите запрос, а потом можете выполнять его с разными параметрами.

Обработка ошибок: как не сломать сайт

Ошибки в SQL-запросах могут возникнуть по разным причинам: опечатка в имени таблицы, неверный тип данных, нарушение уникальности. Если их не обрабатывать, пользователь увидит либо пустую страницу, либо (что хуже) сообщение с деталями, которые могут помочь злоумышленнику.

В PDO есть несколько режимов обработки ошибок. Самый удобный — PDO::ERRMODE_EXCEPTION, который выбрасывает исключение при любой ошибке. Мы уже установили его при подключении. Теперь можно ловить исключения в блоке try-catch:

prepare("SELECT * FROM non_existent_table");
    $stmt->execute();
} catch (PDOException $e) {
    // Логируем ошибку, а пользователю показываем что-то нейтральное
    error_log($e->getMessage());
    echo "Произошла ошибка. Попробуйте позже.";
}
?>

Такой подход скрывает детали от пользователя, но сохраняет их в логах для разработчика.

Лайфхак: Настройте отдельный файл для подключения к базе данных (например, db.php) и подключайте его через require в нужных местах. Так вы не будете дублировать код и сможете легко изменить параметры подключения.

Безопасность превыше всего: SQL-инъекции и как с ними бороться

SQL-инъекция — это когда злоумышленник вставляет в запрос свой код через поля ввода. Например, если вы делаете так:

query($sql);
?>

И пользователь передаст name=' OR '1'='1, то запрос вернёт всех пользователей. А если передаст name='; DROP TABLE users; --, то вы потеряете таблицу. Страшно? Ещё бы.

Спасают подготовленные выражения. Они разделяют код запроса и данные, поэтому инъекция невозможна. Вот безопасный вариант:

prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute(['name' => $_GET['name']]);
$result = $stmt->fetchAll();
?>

Всегда используйте подготовленные выражения. Это правило номер один.

Также полезно экранировать специальные символы, но подготовленные запросы надёжнее.

Сравнение расширений MySQL в PHP

Чтобы вы могли выбрать инструмент под задачу, вот таблица с основными характеристиками трёх расширений.

Расширение Поддержка в PHP Объектный стиль Подготовленные запросы Универсальность
mysql Удалено в PHP 7.0 Нет Нет Только MySQL
mysqli Да Да Да Только MySQL
PDO Да Да Да 12+ баз данных

Как видите, PDO выигрывает по универсальности. Если в будущем вы решите сменить MySQL на PostgreSQL, код почти не придётся менять.

Практические советы для повседневной работы

  • Закрывайте соединение. В PHP соединение закрывается автоматически в конце скрипта, но если работаете с длительными процессами, лучше явно обнулить объект: $conn = null;.
  • Используйте транзакции для нескольких связанных запросов (например, перевод денег между счетами). Это гарантирует целостность данных.
  • Выбирайте только нужные поля. Не пишите SELECT *, если нужны только имя и email — это лишняя нагрузка.
  • Индексируйте поля, по которым часто ищете (WHERE, JOIN). Но не увлекайтесь: индексы замедляют вставку.
  • Храните пароли в хешированном виде. Используйте password_hash() и password_verify().
Совет: Для отладки запросов используйте метод $stmt->debugDumpParams() в PDO или $conn->error в mysqli. Но никогда не выводите отладочную информацию на продакшене.

Что в итоге?

Мы разобрали основы работы с MySQL в PHP. Главные выводы:

  • Используйте PDO или mysqli — забудьте про устаревшее расширение mysql.
  • Всегда применяйте подготовленные выражения для защиты от инъекций.
  • Обрабатывайте ошибки через исключения и логируйте их.
  • Следите за безопасностью: хешируйте пароли, не доверяйте пользовательскому вводу.
  • Практикуйтесь на простых проектах: список задач, гостевой блог, каталог книг.

Базы данных — это мощный инструмент. Освоив его, вы сможете создавать по-настоящему полезные веб-приложения. Не бойтесь экспериментировать и читать документацию. Удачи!

Студия WNDER