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();
}

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

- соединение mysql php (соединение с mysql из php)
- Php mysql server (mysql сервер php)
- Php mysql (работа с mysql в php)

Дополнительные примеры с расширенными возможностями 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 ? + ?');
// смешивание не приветствуется

MySQLi в PHP - comments

En
Php mysqli (php)