MySQLi в PHP: практические методы работы с данными
Основы работы с MySQLi в PHP
MySQLi (MySQL Improved) - расширение PHP для работы с базами данных MySQL, предоставляющее как процедурный, так и объектно-ориентированный интерфейс. Оно поддерживает подготовленные запросы, транзакции, множественные запросы и улучшенную обработку ошибок. Ниже рассмотрены основные варианты использования.
Как организовать безопасное подключение и выполнение запросов с помощью MySQLi?
Наиболее эффективное решение - объектно-ориентированный подход с использованием класса mysqli. Он обеспечивает чистое управление ресурсами и удобную цепочку вызовов.
// Пример подключения к БД
$host = 'localhost';
$user = 'root';
$pass = 'password';
$db = 'test';
$mysqli = new mysqli($host, $user, $pass, $db);
// Проверка соединения
if ($mysqli->connect_errno) {
die('Ошибка подключения: ' . $mysqli->connect_error);
}
// Выполнение запроса
$result = $mysqli->query('SELECT id, name FROM users');
// Получение данных
while ($row = $result->fetch_assoc()) {
echo 'ID: ' . $row['id'] . ', Name: ' . $row['name'] . "\n";
}
// Освобождение результата
$result->free();
$mysqli->close();
Phpmyadmin php (phpmyadmin в php)
ID: 1, Name: Alice ID: 2, Name: Bob
Php having (оператор having в sql (php))
Типичные ошибки:
- Ошибка соединения: неверный хост, пользователь или пароль. Решение - проверить учетные данные и запущен ли сервер MySQL.
- Ошибка запроса: синтаксическая ошибка в SQL. Используйте
$mysqli->errorдля получения текста ошибки. - Утечка памяти при отсутствии
free()после fetch. Рекомендуется освобождать результат явно.
Как выполнить запрос с подготовленным выражением для защиты от SQL-инъекций?
Подготовленные запросы (prepared statements) являются безопасным вариантом при работе с пользовательскими данными. Они отделяют логику SQL от данных.
$stmt = $mysqli->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
$stmt->bind_param('ss', $name, $email);
$name = 'John';
$email = 'john@example.com';
$stmt->execute();
$name = 'Jane';
$email = 'jane@example.com';
$stmt->execute();
$stmt->close();
Php sql (php и sql)
(нет вывода, записи вставлены)
Sql запрос php (sql запрос в php)
Проблема: неправильное указание типов в bind_param (например, 'i' для целого, 's' для строки) может привести к неожиданным результатам. Всегда проверяйте соответствие типов.
Как обрабатывать ошибки в процедурном стиле MySQLi?
Процедурный стиль - альтернатива ООП. Он использует функции mysqli_connect() и т.д. Подходит для простых скриптов.
$link = mysqli_connect($host, $user, $pass, $db);
if (!$link) {
die('Ошибка: ' . mysqli_connect_error());
}
$query = 'SELECT * FROM users';
$result = mysqli_query($link, $query);
if (!$result) {
die('Ошибка запроса: ' . mysqli_error($link));
}
while ($row = mysqli_fetch_assoc($result)) {
print_r($row);
}
mysqli_free_result($result);
mysqli_close($link);
Php mysql select (выборка данных из mysql)
Ошибка: смешение стилей (ООП и процедурного) может затруднить поддержку кода. Рекомендуется придерживаться одного подхода.
Как использовать транзакции в MySQLi?
Транзакции обеспечивают атомарность операций. В MySQLi можно явно управлять транзакциями.
$mysqli->begin_transaction();
try {
$mysqli->query('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
$mysqli->query('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
$mysqli->commit();
} catch (Exception $e) {
$mysqli->rollback();
echo 'Транзакция отменена: ' . $e->getMessage();
}
Проблема: если не использовать исключения, ошибка в одном запросе может оставить данные в несогласованном состоянии. Рекомендуется всегда проверять результат каждого запроса.
Дополнительные примеры с расширенными возможностями MySQLi
Пример 1: Получение результата в виде объектов
$result = $mysqli->query('SELECT id, name, email FROM users');
while ($obj = $result->fetch_object()) {
echo $obj->id . ' ' . $obj->name . ' ' . $obj->email . "\n";
}
1 Alice alice@example.com 2 Bob bob@example.com
Пример 2: Использование bind_result для получения результатов подготовленного запроса
$stmt = $mysqli->prepare('SELECT name, email FROM users WHERE id = ?');
$stmt->bind_param('i', $id);
$id = 1;
$stmt->execute();
$stmt->bind_result($name, $email);
while ($stmt->fetch()) {
echo "Name: $name, Email: $email\n";
}
$stmt->close();
Name: Alice, Email: alice@example.com
Пример 3: Множественные запросы (multi_query) - выполнение нескольких SQL-команд за один вызов
$sql = "INSERT INTO log (action) VALUES ('login'); UPDATE users SET last_login=NOW() WHERE id=1;";
if ($mysqli->multi_query($sql)) {
do {
// обрабатываем каждый результат, если есть
if ($result = $mysqli->store_result()) {
$result->free();
}
} while ($mysqli->more_results() && $mysqli->next_result());
} else {
echo 'Ошибка: ' . $mysqli->error;
}
(нет вывода, запросы выполнены)
Важно:
multi_query может быть использован для SQL-инъекций, если строка $sql содержит пользовательские данные. Необходимо экранировать или использовать подготовленные запросы отдельно.Пример 4: Работа с хранимыми процедурами
$stmt = $mysqli->prepare('CALL get_users_by_status(?)');
$stmt->bind_param('s', $status);
$status = 'active';
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$result->free();
$stmt->close();
Array ( [id] => 1 [name] => Alice [status] => active ) Array ( [id] => 2 [name] => Bob [status] => active )
Пример 5: Получение информации о столбцах результата (field_count, fetch_fields)
$result = $mysqli->query('SELECT * FROM users LIMIT 0'); // запрос без строк
$fields = $result->fetch_fields();
foreach ($fields as $field) {
echo $field->name . ' (' . $field->type . ')' . "\n";
}
id (int) name (string) email (string) status (string)
Пример 6: Автоматическое переключение между ООП и процедурным стилем - не рекомендуется, но возможно
$link = mysqli_connect(...);
$stmt = mysqli_prepare($link, 'SELECT ? + ?');
// смешивание не приветствуется