Работа с базами данных SQL в PHP: от подключения до транзакций

Раздел: Базы данных -> Работа с базами данных SQL в PHP

Подключение и выполнение запросов к SQL из PHP

Какое расширение PHP является наиболее эффективным и современным для работы с SQL?

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


$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8mb4';
$user = 'root';
$password = '';
$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, $password, $options);
} catch (PDOException $e) {
    die('Ошибка подключения: ' . $e->getMessage());
}
  

Php class sql (класс для работы с sql в php)

В этом примере задан DSN (Data Source Name) для MySQL, указаны имя пользователя и пароль, а также настройки: генерация исключений при ошибках, режим выборки по умолчанию (ассоциативный массив) и отключение эмуляции подготовленных запросов для использования реальной многоразовой подготовки.

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


$stmt = $pdo->query('SELECT id, name FROM users');
while ($row = $stmt->fetch()) {
    echo $row['name'] . '\n';
}
  

Php sql insert (insert в php)

Типичная ошибка: неверные параметры подключения

Ошибка SQLSTATE[HY000] [1045] Access denied означает неверный логин или пароль. Решение: проверьте учётные данные и права доступа.

Ошибка could not find driver возникает, если в PHP не установлен драйвер PDO для используемой СУБД (например, pdo_mysql). Установите расширение через менеджер пакетов вашей ОС или в php.ini.

Как использовать расширение mysqli (MySQL Improved) в процедурном стиле?

Расширение mysqli предназначено только для MySQL и поддерживает как процедурный, так и объектно-ориентированный стиль. Пример процедурного подключения:


$link = mysqli_connect('localhost', 'root', '', 'mydb');
if (!$link) {
    die('Ошибка подключения: ' . mysqli_connect_error());
}
mysqli_set_charset($link, 'utf8mb4');
$result = mysqli_query($link, 'SELECT id, name FROM users');
while ($row = mysqli_fetch_assoc($result)) {
    echo $row['name'] . '\n';
}
mysqli_close($link);
  

Php ms sql (работа с ms sql в php)

Цель использования mysqli - работа исключительно с MySQL, особенно в проектах, где не требуется смена СУБД. Встроенная поддержка подготовленных запросов также присутствует, но синтаксис более громоздкий.

Проблема: смешивание функций mysql_* и mysqli_*

Использование устаревшего расширения mysql (удалено в PHP 7) приведёт к фатальным ошибкам. Мигрируйте на mysqli или PDO.

Как выполнять запросы с параметрами, защищёнными от SQL-инъекций, в PDO?

Подготовленные запросы (prepared statements) - основной способ безопасной передачи параметров. Пример:


$sql = 'SELECT name, email FROM users WHERE id = :id';
$stmt = $pdo->prepare($sql);
$stmt->execute([':id' => 42]);
$user = $stmt->fetch();
  

переменную sql php (использование переменных в sql-запросах php)

Здесь плейсхолдер :id заменяется на значение 42, причём экранирование выполняется автоматически. Альтернативно можно использовать позиционные плейсхолдеры ?.

Ошибка: использование разных типов плейсхолдеров в одном запросе

Смешивание именованных (:name) и позиционных (?) плейсхолдеров в одном запросе вызовет ошибку. Выберите один стиль.

Как обрабатывать ошибки выполнения запросов?

В PDO удобно использовать режим исключений (ERRMODE_EXCEPTION). Пример с try-catch:


try {
    $pdo->exec('INSERT INTO users (name) VALUES ("Иван")');
    echo 'Добавлено успешно';
} catch (PDOException $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
  

В mysqli можно проверять mysqli_errno() или mysqli_error().

Забытый коммит транзакции

При использовании транзакций без автоматического коммита все изменения будут откачены при завершении скрипта, если не вызван commit(). Всегда проверяйте успешность и вызывайте rollback() в случае ошибки.

Какие цели и случаи использования каждого варианта?

PDO - универсальное решение для проектов, где требуется поддержка нескольких СУБД или переносимость кода. Идеально для современных приложений, фреймворков (Laravel, Symfony). mysqli - выбор для быстрой интеграции с MySQL без дополнительных абстракций, если проект не планирует менять СУБД. Устаревшее mysql не рассматривается из-за полной небезопасности и удаления из PHP.

- Php sql connect (подключение к sql в php)
- Php database sql (работа с базами данных sql в php)
- Sql where php (условие where в sql-запросах php)

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

Пример транзакции с PDO

Транзакции позволяют выполнить несколько запросов как единое целое. Если один запрос ошибочен, все изменения откатываются.

Пример

try {
    $pdo->beginTransaction();
    $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 (PDOException $e) {
    $pdo->rollBack();
    echo 'Ошибка: ' . $e->getMessage();
}

Результат: При успешном выполнении обоих UPDATE данные изменятся. При ошибке (например, отрицательный баланс) изменения откатятся.

(при успехе) Перевод успешен
(при ошибке) Ошибка: ...

Массовая вставка с подготовленным запросом

Для вставки нескольких записей эффективно использовать один подготовленный запрос, повторяя его в цикле с разными данными.

Пример

$pdo->beginTransaction();
$sql = 'INSERT INTO products (name, price) VALUES (:name, :price)';
$stmt = $pdo->prepare($sql);

$products = [
    ['name' => 'Товар1', 'price' => 100],
    ['name' => 'Товар2', 'price' => 200],
    ['name' => 'Товар3', 'price' => 150],
];

foreach ($products as $product) {
    $stmt->execute($product);
}

$pdo->commit();
echo 'Вставлено ' . count($products) . ' записей';

Результат - все три товара добавлены в таблицу за одну транзакцию.

Вставлено 3 записи

Выборка данных в виде объектов

PDO может извлекать строки как объекты заданного класса.

Пример

class User {
    public $id;
    public $name;
    public $email;
}

$stmt = $pdo->query('SELECT id, name, email FROM users');
$users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
foreach ($users as $user) {
    echo $user->name . ' (' . $user->email . ')' . PHP_EOL;
}

Результат - каждая строка становится объектом User с публичными свойствами, названия которых совпадают с именами столбцов.

Обработка ошибок в mysqli с использованием исключений

В mysqli можно включить режим исключений, установив MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT.

Пример

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect('localhost', 'root', '', 'mydb');
$result = mysqli_query($link, 'SELECT * FROM nonexistent');

При ошибке (например, несуществующая таблица) скрипт выбросит исключение mysqli_sql_exception. Без этого режима ошибки молча возвращают false, и их нужно проверять вручную.

Получение количества затронутых строк

После UPDATE, DELETE или INSERT можно получить количество изменённых строк через rowCount() в PDO или mysqli_affected_rows() в mysqli.

Пример

$stmt = $pdo->exec('DELETE FROM logs WHERE date < "2020-01-01"');
echo 'Удалено строк: ' . $stmt; // для exec возвращается количество
// или
$stmt = $pdo->prepare('DELETE FROM logs WHERE date < :date');
$stmt->execute([':date' => '2020-01-01']);
echo 'Удалено строк: ' . $stmt->rowCount();

Работа с базами данных SQL в PHP - comments

En
Php database sql (php)