Работа с MySQL в PHP: выбор расширения и практические примеры

Раздел: Базы данных -> Функции БД

Основы работы с MySQL в PHP

Как эффективно и безопасно взаимодействовать с базой данных MySQL из PHP?

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

Пример подключения к MySQL через PDO:


<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
$username = 'user';
$password = 'pass';
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
    $pdo = new PDO($dsn, $username, $password, $options);
    echo 'Соединение установлено';
} catch (PDOException $e) {
    echo 'Ошибка подключения: ' . $e->getMessage();
}
?>
  

Mysql functions php (функции mysql в php)

В коде задаётся DSN – строка с именем хоста, именем базы и кодировкой. Опции включают режим ошибок (исключения) и способ извлечения данных (ассоциативный массив). Блок try/catch обрабатывает неудачное подключение.

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

  • Неверные учётные данные – ловится исключением PDOException.
  • Отсутствие расширения PDO или драйвера mysql – проверяется через extension_loaded('pdo_mysql').
  • Проблемы с кодировкой – указывать charset в DSN обязательно (utf8mb4 для эмодзи).

Как выполнять запросы с помощью PDO?

Для простых запросов без пользовательских данных используется метод query(). Пример выборки всех записей:


$stmt = $pdo->query('SELECT * FROM users');
$users = $stmt->fetchAll();
foreach ($users as $user) {
    echo $user['name'] . '<br>';
}
  

Для запросов с параметрами обязательны подготовленные выражения – метод prepare() и execute(). Это предотвращает SQL-инъекции.


$sql = 'SELECT * FROM users WHERE email = :email';
$stmt = $pdo->prepare($sql);
$stmt->execute(['email' => 'user@example.com']);
$user = $stmt->fetch();
  

Именованные плейсхолдеры (:email) более читаемы. Возможна также позиционная подстановка (?).

Проблемы:

  • Забыли выполнить prepare – прямой подстановкой данных увеличивается риск инъекций.
  • Несовпадение типов (например, передача строки вместо числа) – PDO может привести к неожиданным ошибкам, лучше явно указывать типы через bindValue().

Как работать с MySQL через расширение mysqli?

mysqli – альтернатива, специфичная только для MySQL. Доступно два стиля: объектно-ориентированный и процедурный.

Объектный стиль:


$mysqli = new mysqli('localhost', 'user', 'pass', 'testdb');
if ($mysqli->connect_error) {
    die('Ошибка: ' . $mysqli->connect_error);
}
$result = $mysqli->query('SELECT * FROM users');
while ($row = $result->fetch_assoc()) {
    echo $row['name'];
}
  

Процедурный стиль:


$link = mysqli_connect('localhost', 'user', 'pass', 'testdb');
if (!$link) {
    die('Ошибка: ' . mysqli_connect_error());
}
$result = mysqli_query($link, 'SELECT * FROM users');
while ($row = mysqli_fetch_assoc($result)) {
    echo $row['name'];
}
  

Подготовленные выражения в mysqli:


$stmt = $mysqli->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
$stmt->bind_param('ss', $name, $email);
$name = 'Alex';
$email = 'alex@example.com';
$stmt->execute();
  

Строка 'ss' означает два строковых параметра. Доступны типы: i (int), d (double), s (string), b (blob).

Ошибки и ограничения:

  • Не забыть проверить connect_error – при ошибке объект может быть частично создан.
  • Процедурный стиль сложнее поддерживать, но быстрее пишется в простых скриптах.
  • Подготовленные выражения в mysqli требуют явного указания типов, что может запутать.
Как использовать устаревшее расширение mysql_*?

Расширение mysql_* удалено из PHP 7.0 и не должно применяться в новых проектах. Пример (только для справки):


$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('testdb', $link);
$result = mysql_query('SELECT * FROM users');
while ($row = mysql_fetch_assoc($result)) {
    echo $row['name'];
}
  

Проблемы:

  • Функции объявлены устаревшими и удалены, нет поддержки подготовленных выражений.
  • Нет объектной модели, только процедурный стиль.
  • Высокая вероятность SQL-инъекций.

Случаи использования: только при работе с легаси-кодом на PHP 5.x. Для новых разработок выбирают PDO или mysqli.

Расширенные примеры работы с MySQL в PHP

Пример 1. Транзакции в PDO

Перевод денег между счетами требует атомарности. PDO поддерживает транзакции.

Пример

<?php
$pdo->beginTransaction();
try {
    $pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
    $pdo->exec('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
    $pdo->commit();
    echo 'Перевод выполнен успешно';
} catch (Exception $e) {
    $pdo->rollBack();
    echo 'Ошибка: ' . $e->getMessage();
}
?>
Перевод выполнен успешно
(при условии, что начальные балансы позволяют списание)

Пример 2. Массовая вставка через подготовленные выражения

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

Пример

<?php
$data = [
    ['Anna', 'anna@example.com'],
    ['Bob', 'bob@example.com'],
    ['Charlie', 'charlie@example.com']
];
$sql = 'INSERT INTO users (name, email) VALUES (:name, :email)';
$stmt = $pdo->prepare($sql);
foreach ($data as $row) {
    $stmt->execute(['name' => $row[0], 'email' => $row[1]]);
}
echo 'Вставлено ' . count($data) . ' записей';
?>
Вставлено 3 записи

Пример 3. Вызов хранимой процедуры с выходными параметрами в mysqli

Пример

<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'testdb');
$stmt = $mysqli->prepare('CALL get_user_count(?)');
$stmt->bind_param('i', $dummy);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
echo 'Количество пользователей: ' . $row['cnt'];
?>

Предполагается, что процедура get_user_count возвращает результат как SELECT.

Пример 4. Обработка результатов с курсором (PDO)

Пример

<?php
$stmt = $pdo->prepare('SELECT * FROM logs ORDER BY id', [
    PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL
]);
$stmt->execute();
// Перемещение по результатам без извлечения всех строк сразу
$row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST);
echo 'Последняя запись: ' . $row['message'];
?>

Пример 5. Динамическое построение запроса (безопасное) с помощью IN()

Пример

<?php
$ids = [1, 2, 3, 5];
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$sql = "SELECT * FROM products WHERE id IN ($placeholders)";
$stmt = $pdo->prepare($sql);
$stmt->execute($ids);
$products = $stmt->fetchAll();
foreach ($products as $p) {
    echo $p['name'] . '<br>';
}
?>

Функции MySQL в PHP - comments

En
Mysql functions php (php)