Работа с MySQL в PHP: подключение и основные приёмы

Раздел: Базы данных -> Подключение к MySQL

Основное решение: подключение через PDO

Каким образом обеспечить безопасное и универсальное соединение с MySQL?

PDO (PHP Data Objects) - это современный интерфейс для работы с базами данных, поддерживающий множество СУБД, включая MySQL. Он использует подготовленные запросы, что снижает риск SQL-инъекций.


<?php
$host = 'localhost';
$db   = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    die('Ошибка подключения: ' . $e->getMessage());
}
?>
  

Пояснение шагов: сначала формируется DSN - строка, содержащая тип СУБД, хост, имя базы и кодировку. Затем создаётся объект PDO с передачей DSN, имени пользователя и пароля. Массив options задаёт режим ошибок (исключения), режим выборки (ассоциативные массивы) и отключает эмуляцию подготовленных запросов (рекомендуется для реальной поддержки). Блок try-catch перехватывает исключения, чтобы корректно обработать сбой подключения.

Цель использования: когда требуется гибкость (возможность смены СУБД без переписывания кода) и повышенная безопасность за счёт обязательного применения подготовленных запросов.

Типичные ошибки:

  • Исключение PDOException с сообщением could not find driver - отсутствует установленное расширение PDO MySQL. Решение: включить extension=pdo_mysql в php.ini.
  • Ошибка Access denied for user - неверные учётные данные. Проверить имя пользователя, пароль и права доступа к базе.
  • Ошибка Unknown database - указанная БД не существует. Создать её через SQL или убедиться в правильности имени.

Варианты подключения

Как выполнить подключение через расширение mysqli (процедурный стиль)?

Расширение mysqli предназначено только для MySQL. Процедурный подход удобен для начинающих и быстрого прототипирования.


<?php
$link = mysqli_connect('localhost', 'root', '', 'test');
if (!$link) {
    die('Ошибка соединения: ' . mysqli_connect_error());
}
echo 'Успешно подключено';
mysqli_close($link);
?>
  

Пояснение: mysqli_connect принимает хост, пользователя, пароль и имя БД. Возвращает ресурс соединения. Проверка !$link выявляет неудачу. Функция mysqli_close закрывает соединение.

Цель использования: простота для проектов, работающих только с MySQL, и когда нет необходимости в поддержке других СУБД.

Проблемы: процедурный стиль не поддерживает исключения, ошибки обрабатываются вручную. Нужно явно экранировать данные через mysqli_real_escape_string.

Как использовать объектно-ориентированный стиль mysqli?

Этот вариант даёт более структурированный код, схожий с PDO.


<?php
$mysqli = new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) {
    die('Ошибка подключения: ' . $mysqli->connect_error);
}
echo 'Успешно';
$mysqli->close();
?>
  

Пояснение: Конструктор new mysqli возвращает объект. Свойство connect_error содержит текст ошибки, если соединение не удалось. Метод close() завершает сеанс.

Цель использования: когда предпочтителен ООП-подход, но СУБД строго MySQL.

Распространённая ошибка: попытка выполнить запрос до проверки успешности подключения - приводит к фатальной ошибке. Всегда проверять $mysqli->connect_error.

Как подключаться с помощью устаревшего расширения mysql (на PHP 5.x)?

Это расширение удалено из PHP 7 и выше. Использовать его только в целях изучения или при миграции старого кода.


<?php
$link = mysql_connect('localhost', 'root', '');
if (!$link) {
    die('Ошибка: ' . mysql_error());
}
mysql_select_db('test', $link);
echo 'Подключено';
mysql_close($link);
?>
  

Пояснение: mysql_connect возвращает ресурс, mysql_select_db выбирает базу. Все функции устарели, их использование небезопасно.

Цель использования: работа с legacy-проектами, не обновлёнными до современных версий PHP.

Проблемы: mysql_* функции не поддерживают подготовленные запросы, подвержены SQL-инъекциям. В современных PHP они удалены, что вызывает фатальную ошибку.

Расширенные примеры кода

Пример

<?php
// Пример 1: PDO с транзакциями и подготовленными запросами
$dsn = 'mysql:host=localhost;dbname=shop;charset=utf8mb4';
$pdo = new PDO($dsn, 'root', '', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

try {
    $pdo->beginTransaction();
    $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
    $stmt->execute([':name' => 'Иван', ':email' => 'ivan@example.com']);
    $pdo->commit();
    echo 'Транзакция выполнена успешно.';
} catch (Exception $e) {
    $pdo->rollBack();
    echo 'Ошибка: ' . $e->getMessage();
}
?>
Транзакция выполнена успешно.

Пояснение: В этом примере демонстрируется использование транзакций для гарантии целостности данных. Подготовленный запрос с именованными параметрами предотвращает инъекции. Если любой из запросов внутри транзакции завершается ошибкой, выполняется откат.

Пример

<?php
// Пример 2: mysqli с подготовленным запросом (объектный стиль)
$mysqli = new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) {
    die('Ошибка: ' . $mysqli->connect_error);
}
$stmt = $mysqli->prepare('SELECT id, name FROM users WHERE email = ?');
$email = 'test@example.com';
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    echo 'ID: ' . $row['id'] . ' Имя: ' . $row['name'] . '\n';
}
$stmt->close();
$mysqli->close();
?>
ID: 1 Имя: Иван
ID: 3 Имя: Мария

Пояснение: bind_param принимает тип параметра ('s' - строка) и переменную. После выполнения извлекается результат через get_result().

Пример

<?php
// Пример 3: PDO с обработкой ошибок через исключения и получение одной строки
$pdo = new PDO('mysql:host=localhost;dbname=blog', 'root', '', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
$stmt = $pdo->query('SELECT * FROM posts LIMIT 1');
$post = $stmt->fetch();
print_r($post);
?>
Array
(
    [id] => 1
    [title] => Первая запись
    [content] => Текст поста
    [created_at] => 2025-03-01 10:00:00
)

Пояснение: Использование query для простых запросов без параметров. Результат выводится в виде ассоциативного массива.

Пример

<?php
// Пример 4: Подключение через PDO с использованием файла конфигурации
// config.php
return [
    'dsn' => 'mysql:host=10.0.0.1;dbname=analytics;charset=utf8',
    'user' => 'analyst',
    'pass' => 'secret123',
];

// app.php
$config = require 'config.php';
try {
    $pdo = new PDO($config['dsn'], $config['user'], $config['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    error_log('Не удалось подключиться: ' . $e->getMessage());
    exit('Временная недоступность сервиса');
}
?>
(нет вывода, соединение устанавливается без ошибок)

Пояснение: Вынесение параметров подключения в отдельный файл упрощает настройку на разных окружениях. Обработка ошибок записывается в лог вместо вывода пользователю.

Подключение MySQL к PHP - comments

En
подключение mysql php (php)