NULL и расширение mysqli: примеры кода
NULL в mysqli: ключевые подходы
Наиболее надёжный способ работы с NULL в расширении mysqli - использование подготовленных запросов (prepared statements). Этот метод автоматически распознаёт null в переменных PHP и передаёт в базу данных именно SQL-значение NULL, избегая путаницы с пустыми строками или строкой 'NULL'.
Пример: вставка NULL через prepared statement
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$name = 'Иван';
$email = null; // переменная равна NULL
$stmt->bind_param('ss', $name, $email); // тип 's' для обоих, NULL передаётся корректно
$stmt->execute();
$stmt->close();
Php mysqli null (обработка null в mysqli)
В результате в поле email будет записан SQL NULL, а не пустая строка. При выборке используйте is_null() или строгое сравнение === null.
Типичная ошибка: попытка проверить NULL через if (!$email) - такое условие сработает и для пустой строки, и для нуля, и для false. Правильно: if (is_null($email)).
Как вставить NULL без подготовленных запросов?
Иногда требуется выполнить запрос без prepared statements (например, в старом коде). В таком случае NULL вставляется прямым текстом в SQL.
$name = 'Пётр';
$email = null;
// Неправильно: строка 'NULL' будет воспринята как текст
$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')"; // Ошибка!
// Правильно:
if ($email === null) {
$sql = "INSERT INTO users (name, email) VALUES ('$name', NULL)";
} else {
$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
}
Проблема: ручная подстановка значений создаёт риск SQL-инъекций. Если $name содержит кавычку, запрос сломается. Использовать такой подход можно только при полном контроле над данными. Рекомендуется: перейти на prepared statements.
Как проверить на NULL после выборки данных?
При извлечении строки из результата запроса значения полей могут быть NULL. Проверять нужно строго.
$stmt = $mysqli->prepare("SELECT name, email FROM users WHERE id = ?");
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($name, $email);
$stmt->fetch();
if (is_null($email)) {
echo "Email не указан";
} else {
echo "Email: $email";
}
$stmt->close();
Ошибка: использование if ($email == null) работает, но if ($email == '') ложно для NULL. Чтобы избежать путаницы, всегда применяйте is_null() или === null.
Как заменить NULL на значение по умолчанию при выводе?
На стороне SQL можно воспользоваться функцией COALESCE или IFNULL. В PHP - оператором ?? (null coalescing).
// SQL-запрос
$sql = "SELECT COALESCE(email, 'не указан') AS email_display FROM users";
// PHP после fetch:
$email = $row['email_display']; // уже заменён
// Или в PHP:
$email = $row['email'] ?? 'не указан';
Обратите внимание: COALESCE заменяет только NULL, пустая строка не заменяется.
Распространённая ошибка: в SQL пишут WHERE email = NULL - это всегда ложь. Нужно WHERE email IS NULL.
Как правильно сравнивать с NULL в условиях SQL?
NULL в SQL - неизвестное значение, сравнение через = или != не работает. Используйте IS NULL и IS NOT NULL.
// Выбрать пользователей без email
$sql = "SELECT * FROM users WHERE email IS NULL";
// Выбрать пользователей с email
$sql = "SELECT * FROM users WHERE email IS NOT NULL";
Типичная ошибка: попытка использовать WHERE email = NULL - запрос вернёт пустой результат, так как NULL != NULL. Всегда пишите IS NULL.
Расширенные примеры обработки NULL в mysqli
Ниже приведены сценарии с подробными комментариями и выводами.
// Пример 1: Вставка NULL в поле с типом INT и проверка
$stmt = $mysqli->prepare("INSERT INTO products (name, price) VALUES (?, ?)");
$name = 'Услуга';
$price = null; // цена не указана
$stmt->bind_param('sd', $name, $price); // 'd' для double, null передаётся как NULL
$stmt->execute();
echo "Вставлена запись с ID: " . $stmt->insert_id;
// Результат: Вставлена запись с ID: 1 (поле price = NULL)
Вставлена запись с ID: 1
// Пример 2: Выборка с обработкой NULL через COALESCE и проверка в PHP
$stmt = $mysqli->prepare("SELECT name, COALESCE(price, 0) AS price_fixed FROM products");
$stmt->execute();
$stmt->bind_result($name, $price_fixed);
while ($stmt->fetch()) {
echo "Товар: $name, Цена: $price_fixed\n";
}
$stmt->close();
// Результат: Товар: Услуга, Цена: 0 (NULL заменён на 0)
Товар: Услуга, Цена: 0
// Пример 3: Обновление поля на NULL через prepared statement
$stmt = $mysqli->prepare("UPDATE users SET phone = ? WHERE id = ?");
$phone = null; // удаляем номер телефона
$id = 5;
$stmt->bind_param('si', $phone, $id);
$stmt->execute();
echo "Обновлено строк: " . $stmt->affected_rows;
// Результат: Обновлено строк: 1 (поле phone стало NULL)
Обновлено строк: 1
// Пример 4: Использование оператора ?? в PHP после fetch_assoc
$result = $mysqli->query("SELECT name, email FROM users LIMIT 1");
$row = $result->fetch_assoc();
$email = $row['email'] ?? 'не указан';
echo "Email: $email";
// Если email NULL, выведет 'не указан'
// Результат: Email: не указан (если NULL)
Email: не указан
// Пример 5: Ошибка при сравнении с NULL в SQL (демонстрация)
$sql = "SELECT * FROM users WHERE email = NULL"; // неверно
$result = $mysqli->query($sql);
echo "Количество строк: " . $result->num_rows; // всегда 0
// Правильный запрос:
$sql = "SELECT * FROM users WHERE email IS NULL";
$result = $mysqli->query($sql);
echo "Количество строк с NULL email: " . $result->num_rows;
Количество строк: 0 Количество строк с NULL email: 3