isset, empty и ?? — как проверить значение
isset($x)— переменная или ключ существует и не равенnull.empty($x)— значение отсутствует или считается ложным:null,false,0,0.0,"","0", пустой массив.$x ?? 'по умолчанию'— значение$x, если оно существует и неnull, иначе — правая часть.
Ни одна из трёх записей не выдаёт предупреждения Undefined variable или Undefined array key, если переменной или ключа нет.
<?php
$values = [null, '', '0', 0, [], 'abc'];
foreach ($values as $value) {
echo json_encode($value) . ': isset=' . (isset($value) ? 'да' : 'нет')
. ', empty=' . (empty($value) ? 'да' : 'нет') . "\n";
}null: isset=нет, empty=да
"": isset=да, empty=да
"0": isset=да, empty=да
0: isset=да, empty=да
[]: isset=да, empty=да
"abc": isset=да, empty=нетЛовушка empty и "0"
empty("0") — true. Если посетитель ввёл в поле количества 0 или имя 0, проверка empty сочтёт поле пустым. Для полей формы надёжнее проверять именно пустую строку:
<?php
$name = trim($_POST['name'] ?? '');
if ($name === '') {
echo 'Введите имя';
}Сначала ?? подставляет пустую строку, если поля нет, потом trim убирает пробелы, и только затем сравнение === ''. Так пройдёт и 0, а строка из одних пробелов — нет.
?? и ?:
<?php
$page = $_GET['page'] ?? 1;
$title = '';
$title = $title ?: 'Без названия';?? смотрит только на существование и null. ?: проверяет, ложно ли значение: 0, "" и "0" он тоже заменит. И главное отличие: если переменной нет, ?: выдаст предупреждение, а ?? — нет.
Запись $config['lang'] ??= 'ru'; задаёт значение, только если его ещё нет (с PHP 7.4).
Ключ со значением null
<?php
$user = ['name' => 'Анна', 'phone' => null];
var_dump(isset($user['phone']));
var_dump(array_key_exists('phone', $user));bool(false)
bool(true)isset не отличает «ключа нет» от «ключ есть, но значение null». Если разница важна (например, поле в базе есть, но не заполнено), используйте array_key_exists.
Что выбрать
| Задача | Запись |
|---|---|
| значение по умолчанию для поля формы или параметра | $_GET['q'] ?? '' |
| отмечен ли флажок | isset($_POST['agree']) |
| поле формы не заполнено | trim($_POST['name'] ?? '') === '' |
| массив пуст | $items === [] или count($items) === 0 |
| есть ли ключ, даже со значением null | array_key_exists('key', $a) |
empty удобна, когда действительно подходят все «пустые» значения — например, для проверки, что в массиве нет элементов. Для чисел и строк из формы она слишком широка.