Перейти к содержимому
Теория · Условия · урок 4 из 8

null, isset и empty

Условие if ($x) спрашивает, истинно ли значение. Но иногда переменной $x в программе нет вовсе: ей не присвоили значение или ошиблись в её имени. Что тогда скажет условие?

PHP
<?php

if ($nickname) { // ✗
    echo 'Hi, ', $nickname, "\n";
}
echo 'next', "\n";
TEXT
Warning: Undefined variable $nickname

Переменная $nickname нигде не получила значения. PHP выдаёт предупреждение, читает её как null, пропускает ветку и печатает next. Программа работает дальше, но предупреждение говорит об ошибке в коде, и оставлять его нельзя.

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

  • таблички нет совсем — переменная не определена;
  • табличка висит, но пустая — в переменной null;
  • на табличке что-то написано — в переменной есть значение.

Для таких проверок в PHP есть три инструмента, и отвечают они на разные вопросы.

Три проверки

isset

isset($x) спрашивает: «табличка висит, и на ней что-то написано?» Ответ true, если переменная существует и её значение не null.

PHP
$city = 'Paris';
$phone = null;
var_dump(isset($city));  // bool(true)
var_dump(isset($phone)); // bool(false)
var_dump(isset($email)); // bool(false)

Разберём по строкам:

  1. В $city лежит строка, поэтому isset даёт true.
  2. В $phone лежит null, и isset даёт false.
  3. $email не определена, и isset даёт false без всякого предупреждения.

Почему нет предупреждения? isset — не функция, а языковая конструкция: часть самого языка, которая проверяет переменную сама, а не получает её значение, как функция. Поэтому отсутствующая переменная не вызывает у isset предупреждения.

Здесь аналогия расходится с PHP. На развилке пустую табличку видно сразу. Но isset не отличает её от отсутствующей: и для $phone = null, и для неопределённой переменной он даёт false.

empty

empty($x) спрашивает: «табличка пустая или её нет совсем?» Ответ true, если переменной нет или её значение ложное — из того же списка, что и в условии. empty($x) работает как !isset($x) || !$x.

PHP
$count = 0;
$title = 'News';
var_dump(empty($count));   // bool(true)
var_dump(empty($title));   // bool(false)
var_dump(empty($missing)); // bool(true)

Разберём по строкам:

  1. 0 — ложное значение, поэтому empty($count) даёт true, хотя переменная задана.
  2. В $title непустая строка, и empty даёт false.
  3. $missing не определена: empty — тоже языковая конструкция, и она молча даёт true.

is_null

is_null($x) спрашивает, пустая ли табличка, то есть равно ли значение именно null. Ответ true только для null. Для 0 и '' is_null даёт false, потому что это не отсутствие, а значения.

Но is_null — обычная функция. Чтобы передать ей значение, PHP сначала читает переменную и на отсутствующей выдаёт то же предупреждение, что и if:

TEXT
Warning: Undefined variable $email

После предупреждения is_null($email) всё равно возвращает true: отсутствующую переменную PHP читает как null.

Сравним три проверки

Значение $xisset($x)empty($x)
переменной нетfalsetrue
nullfalsetrue
0 или ''truetrue
'Anna'truefalse

Этот вопрос часто задают на собеседовании: «Чем отличаются isset, empty и is_null?» Ответ:

  • isset — переменная есть и не равна null, без предупреждений;
  • empty — переменной нет или её значение ложное, тоже без предупреждений;
  • is_null — значение именно null; это функция, и на отсутствующей переменной она предупреждает.

Оператор ??

Как вы уже знаете, $a ?? $b даёт $a, если оно задано и не равно null, а иначе $b. Это isset в форме выражения: $name = $nickname ?? 'guest'; работает как isset($nickname) ? $nickname : 'guest' и тоже обходится без предупреждений.

Частая ошибка

Количество из формы пришло строкой '0', и его наличие проверили через empty:

PHP
$quantity = '0';
if (empty($quantity)) { // ✗
    echo 'enter a quantity', "\n";
} else {
    echo 'ordered: ', $quantity, "\n";
}

Программа печатает enter a quantity, хотя человек ввёл ноль: '0' — ложное значение, и empty считает его пустым. Чтобы отличить «не заполнено» от нуля, проверяйте отсутствие и пустую строку отдельно: if (!isset($quantity) || $quantity === '').

Главное

  • isset($x) даёт true, когда переменная есть и не равна null, и никогда не предупреждает.
  • empty($x) даёт true для отсутствующей переменной и для любого ложного значения, включая 0 и '0'.
  • is_null($x) проверяет только null; это функция, и на неопределённой переменной она выдаёт предупреждение.
  • $a ?? $b — это isset в форме выражения.