W3docs

query

В этой статье рассматривается функция mysqli_query() в PHP, которая используется для выполнения SQL-запросов к базе данных MySQL.

$mysqli->query() выполняет один SQL-оператор в базе данных MySQL через открытое соединение MySQLi. Это простейший способ взаимодействия с MySQL из PHP, поэтому он является правильной отправной точкой — однако, как вы увидите ниже, в тот момент, когда запрос содержит пользовательский ввод, следует использовать подготовленные выражения.

На этой странице рассматривается, что возвращает query(), как читать набор результатов, как функция ведёт себя при запросах на запись, а также ловушка SQL-инъекций, которую необходимо избегать.

Синтаксис

// Object-oriented style
$result = $mysqli->query($sql);

// Procedural style
$result = mysqli_query($mysqli, $sql);

Обе формы делают одно и то же; в этой статье используется объектно-ориентированный стиль.

Что возвращает query()

Возвращаемое значение зависит от типа выполняемого оператора:

Тип запросаПри успехеПри ошибке
SELECT, SHOW, DESCRIBE, EXPLAINобъект mysqli_resultfalse
INSERT, UPDATE, DELETE, CREATE, ...truefalse

Поскольку при ошибке всегда возвращается false, можно ветвить логику по возвращаемому значению с помощью обычного if. Никогда не считайте, что запрос выполнился успешно — опечатка в имени столбца или отсутствующая таблица возвращают false.

Выполнение запроса SELECT

При выполнении SELECT итерируйте по возвращённому результату и извлекайте каждую строку с помощью fetch_assoc() (или fetch_array()), а затем освобождайте результат по завершении:

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");

// Stop early if the connection failed.
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
    exit();
}

$result = $mysqli->query("SELECT id, name FROM users");

if ($result) {
    while ($row = $result->fetch_assoc()) {
        echo $row["id"] . ": " . $row["name"] . "\n";
    }
    $result->free();          // release the result set's memory
} else {
    echo "Query failed: " . $mysqli->error;
}

$mysqli->close();
?>

Цикл while завершается, когда fetch_assoc() возвращает null (строк больше нет). $result->free() освобождает набор результатов, что важно в долго работающих скриптах, выполняющих множество запросов.

Выполнение INSERT, UPDATE и DELETE

Запросы на запись не возвращают набор результатов — при успехе они возвращают true. Чтобы узнать, сколько строк было затронуто, прочитайте $mysqli->affected_rows; чтобы получить auto-increment id только что вставленной строки, прочитайте $mysqli->insert_id:

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");

if ($mysqli->query("UPDATE users SET active = 1 WHERE active = 0")) {
    echo $mysqli->affected_rows . " rows updated";
} else {
    echo "Query failed: " . $mysqli->error;
}

$mysqli->close();
?>

Никогда не вставляйте пользовательский ввод напрямую в запрос

query() принимает строку необработанного SQL, поэтому конкатенация пользовательского ввода открывает дверь для SQL-инъекции — наиболее распространённой уязвимости безопасности баз данных в сети:

// DANGEROUS — do NOT do this
$id = $_GET['id'];
$result = $mysqli->query("SELECT * FROM users WHERE id = $id");

Если посетитель отправит id=0 OR 1=1, этот запрос вернёт всех пользователей. Решение — подготовленное выражение, которое отправляет SQL и значения раздельно, чтобы значения никогда не могли интерпретироваться как SQL:

$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']);   // "i" = integer
$stmt->execute();
$result = $stmt->get_result();

Используйте query() только для фиксированного SQL без пользовательского ввода; для всего, что содержит значения, поступающие извне вашего кода, используйте подготовленные выражения. Полное руководство см. в разделе MySQL prepared statements.

Итоги

  • $mysqli->query() выполняет один SQL-оператор на открытом соединении MySQLi.
  • SELECT возвращает mysqli_result, по которому итерируют с помощью fetch_assoc(); другие операторы возвращают true; любая ошибка возвращает false.
  • После запроса на запись читайте affected_rows, а после INSERTinsert_id.
  • Переходите на подготовленные выражения, как только в запросе появляется пользовательский ввод.

Практика

Практика
Что возвращает $mysqli->query() при успешном выполнении оператора SELECT?
Что возвращает $mysqli->query() при успешном выполнении оператора SELECT?
Was this page helpful?