Полное руководство по обновлению данных в базе данных MySQL с помощью PHP
Обновление данных в базе данных — ключевая операция для веб-приложений с динамическим контентом. Пошаговое руководство с примерами на PHP.
Обновление данных — одна из четырёх базовых операций с базой данных (наряду с вставкой, выборкой и удалением строк). Любое приложение, позволяющее пользователям редактировать профиль, отмечать задачу выполненной или менять цену, опирается на неё. В этой главе показано, как безопасно выполнять запрос UPDATE из PHP — с помощью подготовленных запросов — и как проверить, сколько именно строк было изменено.
В этой главе предполагается, что у вас уже есть рабочее подключение к базе данных. В примерах используется mysqli; эквивалентная версия для PDO приведена в конце.
Синтаксис PHP MySQL UPDATE
Оператор UPDATE изменяет значения существующих строк. Его структура одинакова независимо от того, выполняете ли вы его из консоли MySQL или из PHP:
UPDATE table_name
SET column1 = value1, column2 = value2
WHERE some_column = some_value;table_name— таблица, строки которой нужно изменить.SET— столбцы для изменения и их новые значения. Столбцы, не указанные в этом списке, остаются нетронутыми.WHERE— условие выбора строк для изменения. Этот раздел критически важен. Если его опустить, каждая строка в таблице будет обновлена.
Самая распространённая — и самая разрушительная — ошибка при работе с
UPDATE— это забытый разделWHERE. ЗапросUPDATE users SET active = 0деактивирует всех пользователей в таблице, а не только одного. Всегда дважды проверяйте условиеWHEREперед выполнением обновления на реальных данных.
Обновление данных с помощью подготовленного запроса
Никогда не формируйте запрос UPDATE путём конкатенации пользовательского ввода непосредственно в строку SQL — это открывает уязвимость для SQL-инъекции. Вместо этого используйте подготовленный запрос: напишите запрос с заполнителями ?, а затем привяжите значения отдельно, чтобы база данных воспринимала их строго как данные.
<?php
// Reuse your connection — in practice: require 'db_connect.php';
$conn = mysqli_connect("localhost", "username", "password", "database_name");
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "UPDATE users SET email = ?, age = ? WHERE id = ?";
$stmt = mysqli_prepare($conn, $sql);
$email = "[email protected]";
$age = 31;
$id = 1;
// Type string: s = string, i = integer, d = double, b = blob.
// One letter per placeholder, in order.
mysqli_stmt_bind_param($stmt, "sii", $email, $age, $id);
if (mysqli_stmt_execute($stmt)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_stmt_error($stmt);
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
?>Как это работает шаг за шагом:
mysqli_prepare()отправляет шаблон запроса (с заполнителями?) в MySQL.mysqli_stmt_bind_param()привязывает переменные PHP к этим заполнителям. Первый аргумент,"sii", объявляет тип каждого значения по порядку: строка, затем два целых числа. Количество и порядок букв должны точно совпадать с заполнителями.mysqli_stmt_execute()выполняет запрос и возвращаетtrueв случае успеха иfalseв случае ошибки.
Проверка количества изменённых строк
То, что mysqli_stmt_execute() возвращает true, означает лишь, что запрос выполнился без ошибок — это не значит, что строка действительно изменилась. Если условие WHERE не соответствует ни одной строке (или новые значения идентичны старым), ни одна строка не будет затронута. Используйте mysqli_stmt_affected_rows(), чтобы это выяснить:
<?php
$conn = mysqli_connect("localhost", "username", "password", "database_name");
$sql = "UPDATE users SET age = ? WHERE id = ?";
$stmt = mysqli_prepare($conn, $sql);
$age = 40;
$id = 1;
mysqli_stmt_bind_param($stmt, "ii", $age, $id);
mysqli_stmt_execute($stmt);
$rows = mysqli_stmt_affected_rows($stmt);
if ($rows > 0) {
echo "Updated {$rows} row(s).";
} else {
echo "No row matched, or the value was already up to date.";
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
?>Это различие важно в реальных приложениях: кнопка «Сохранить», сообщающая об успехе даже тогда, когда ничего не было найдено, может скрывать ошибки от пользователей.
Обновление данных с помощью PDO
PDO — более переносимая альтернатива mysqli: один и тот же код работает с MySQL, PostgreSQL, SQLite и другими СУБД, а именованные заполнители делают длинные запросы удобнее для чтения:
<?php
$pdo = new PDO(
"mysql:host=localhost;dbname=database_name;charset=utf8mb4",
"username",
"password",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare(
"UPDATE users SET email = :email, age = :age WHERE id = :id"
);
$stmt->execute([
':email' => '[email protected]',
':age' => 31,
':id' => 1,
]);
echo "Updated " . $stmt->rowCount() . " row(s).";
?>При установленном PDO::ERRMODE_EXCEPTION неудавшийся запрос выбрасывает исключение, которое можно перехватить, вместо того чтобы молча завершиться неудачей. rowCount() — это аналог mysqli_stmt_affected_rows() в PDO.
Рекомендации
- Всегда включайте раздел
WHERE, если вы действительно не собираетесь обновлять каждую строку. - Используйте подготовленные запросы для любых значений, поступающих от пользователя — никогда не используйте конкатенацию строк.
- Соответствие строки типов привязки (
"sii"и т. д.) фактическим типам переменных позволяет избежать неявных преобразований. - Оборачивайте обновления нескольких таблиц в транзакцию, чтобы они либо все завершались успешно, либо все откатывались.
- Создавайте резервную копию важных данных перед выполнением масштабных или разовых обновлений в production-среде.