php проверка переменной на null

Что такое null и как с этим жить: сравнение с null в PHP, тонкости в приведении типов данных

В работе с любыми данными то и дело требуется как-то обозначить их отсутствие. Новички зачастую для этой цели используют значение false, которое, по сути, является не отсутствием данных, а определённым значением типа boolean. Для того, чтобы как-то помечать неопределённость или отсутствие данных, существует специальное значение null. Про false, null и прочее уже немало сказано и добавить что-то оригинальное крайне сложно. Но гораздо сложнее бывает найти баг, вызванный неочевидным поведением этих штуковин. Поэтому, вдохновлённый одним таким багом, самым элегантным в моём послужном списке, я решил написать маленькую шпаргалку на эту тему.

Перегружать пост интересными, но довольно-таки бесполезными определениями из Википедии я не стану. Вместо этого перейду сразу к делу и приведу цитату со страницы php.net, посвящённой null:

До этого момента всё кажется простым, но чтобы так оставалось и дальше, при работе с null нужно придерживаться определённых правил.

Математические операции с null

Во всех математических операциях null ведёт себя аналогично int(0):

Проверка переменной на null

Чтобы точно узнать, что переменная содержит null (то есть, ничего не содержит), нужно использовать либо специальную функцию is_null() либо тождественное сравнение ===, а любые другие способы не подойдут:

Проверка null if-выражениях, а так же в функциях empty() и isset()

Тут переменные с null ведут себя абсолютно предсказуемо, как и любые другие ложные значения (которые в if-выражениях приводятся к false). Но нужно помнить, что это не гарантирует нам, что в переменной находится именно null:

Сравнение двух null

В PHP как гибкое, так и тождественное сравнение двух null всегда возвращает false, в отличие от многих других платформ, где сравнение двух неизвестностей возвращает так же неизвестность (то есть, null).

Поведение null при нетождественном сравнении с приведением типов данных

PHP разрешает сравнивать null-ы не только между собой, но и с другими типами данных. При этом не стоит забывать, что гибкое сравнение в php не является транзитивным, то есть, если два значения равны третьему по отдельности, не гарантирует их равенство между собой. Согласно таблицам приведения типов, гибкое сравнение null при помощи оператора == с разными значениями возвращает разные результаты:

Исследование null в JavaScript (а вместе с ним и загадочного undefined) заслуживает отдельной статьи. Главное отличие состоит в том, что, не смотря на приведение типов, null в JavaScript ничему не равен, кроме самого null и этого самого undefined, хотя в if-выражениях и срабатывает аналогично false. А при сравнении с числами он выдаёт ещё более забавные результаты, чем в PHP.

NULL в MySQL, к примеру, действует гораздо более прямолинейно. Он просто при любых действиях с null (даже при сравнении двух null) возвращает null. С его точки зрения, при любых действиях с неизвестностью в результате получится какая-то другая неизвестность 🙂

Простое правило при работе null, которое помогает избегать проблем

Источник

is_null

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

is_null — Проверяет, является ли значение переменной равным null

Описание

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

Возвращаемые значения

Примеры

Пример #1 Пример использования is_null()

Смотрите также

User Contributed Notes 9 notes

Micro optimization isn’t worth it.

You had to do it ten million times to notice a difference, a little more than 2 seconds

$a===NULL; Took: 1.2424390316s
is_null($a); Took: 3.70693397522s

difference = 2.46449494362
difference/10,000,000 = 0.000000246449494362

The execution time difference between ===NULL and is_null is less than 250 nanoseconds. Go optimize something that matters.

In PHP 7 (phpng), is_null is actually marginally faster than ===, although the performance difference between the two is far smaller.

the following will prove that:

?>

this will print out something like:

10 // null
01 // true
01 // false
01 // 0
01 // 1
01 // »
01 // «\0»
Notice: Undefined variable: var in /srv/www/htdocs/sandbox/null/nulltest.php on line 8
10 // (unset)

For the major quirky types/values is_null($var) obviously always returns the opposite of isset($var), and the notice clearly points out the faulty line with the is_null() statement. You might want to examine the return value of those functions in detail, but since both are specified to return boolean types there should be no doubt.

A second look into the PHP specs tells that is_null() checks whether a value is null or not. So, you may pass any VALUE to it, eg. the result of a function.
isset() on the other hand is supposed to check for a VARIABLE’s existence, which makes it a language construct rather than a function. Its sole porpuse lies in that checking. Passing anything else will result in an error.

Knowing that, allows us to draw the following unlikely conclusion:

isset() as a language construct is way faster, more reliable and powerful than is_null() and should be prefered over is_null(), except for when you’re directly passing a function’s result, which is considered bad programming practice anyways.

Источник

isset

(PHP 4, PHP 5, PHP 7, PHP 8)

isset — Определяет, была ли установлена переменная значением, отличным от null

Описание

Определяет, была ли установлена переменная значением отличным от null

Если были переданы несколько параметров, то isset() вернёт true только в том случае, если все параметры определены. Проверка происходит слева направо и заканчивается, как только будет встречена неопределённая переменная.

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

Возвращаемые значения

Примеры

Пример #1 Пример использования isset()

// В следующем примере мы используем var_dump для вывода
// значения, возвращаемого isset().

$a = «test» ;
$b = «anothertest» ;

Функция также работает с элементами массивов:

Пример #2 isset() и строковые индексы

Результат выполнения данного примера:

Примечания

Замечание: Поскольку это языковая конструкция, а не функция, она не может вызываться при помощи переменных функций.

При использовании isset() на недоступных свойствах объекта, будет вызываться перегруженный метод __isset(), если он существует.

Смотрите также

User Contributed Notes 30 notes

I, too, was dismayed to find that isset($foo) returns false if ($foo == null). Here’s an (awkward) way around it.

Of course, that is very non-intuitive, long, hard-to-understand, and kludgy. Better to design your code so you don’t depend on the difference between an unset variable and a variable with the value null. But «better» only because PHP has made this weird development choice.

In my thinking this was a mistake in the development of PHP. The name («isset») should describe the function and not have the desciption be «is set AND is not null». If it was done properly a programmer could very easily do (isset($var) || is_null($var)) if they wanted to check for this!

The new (as of PHP7) ‘null coalesce operator’ allows shorthand isset. You can use it like so:

You can safely use isset to check properties and subproperties of objects directly. So instead of writing

isset($abc) && isset($abc->def) && isset($abc->def->ghi)

or in a shorter form

you can just write

without raising any errors, warnings or notices.

How to test for a variable actually existing, including being set to null. This will prevent errors when passing to functions.

«empty() is the opposite of (boolean) var, except that no warning is generated when the variable is not set.»

!empty() mimics the chk() function posted before.

in PHP5, if you have

I tried the example posted previously by Slawek:

$foo = ‘a little string’;
echo isset($foo)?’yes ‘:’no ‘, isset($foo[‘aaaa’])?’yes ‘:’no ‘;

He got yes yes, but he didn’t say what version of PHP he was using.

I tried this on PHP 5.0.5 and got: yes no

But on PHP 4.3.5 I got: yes yes

Any foreach or similar will be different before and after the call.

To organize some of the frequently used functions..

Return Values :
Returns TRUE if var exists and has value other than NULL, FALSE otherwise.

isset expects the variable sign first, so you can’t add parentheses or anything.

With this simple function you can check if an array has some keys:

If you regard isset() as indicating whether the given variable has a value or not, and recall that NULL is intended to indicate that a value is _absent_ (as said, somewhat awkwardly, on its manual page), then its behaviour is not at all inconsistent or confusing.

Here is an example with multiple parameters supplied

= array();
$var [ ‘val1’ ] = ‘test’ ;
$var [ ‘val2’ ] = ‘on’ ;

The following code does the same calling «isset» 2 times:

= array();
$var [ ‘val1’ ] = ‘test’ ;
$var [ ‘val2’ ] = ‘on’ ;

Note that isset() is not recursive as of the 5.4.8 I have available here to test with: if you use it on a multidimensional array or an object it will not check isset() on each dimension as it goes.

Imagine you have a class with a normal __isset and a __get that fatals for non-existant properties. isset($object->nosuch) will behave normally but isset($object->nosuch->foo) will crash. Rather harsh IMO but still possible.

// pretend that the methods have implementations that actually try to do work
// in this example I only care about the worst case conditions

// if property does not exist <
echo «Property does not exist!» ;
exit;
// >
>

$obj = new FatalOnGet ();

Uncomment the echos in the methods and you’ll see exactly what happened:

On a similar note, if __get always returns but instead issues warnings or notices then those will surface.

The following is an example of how to test if a variable is set, whether or not it is NULL. It makes use of the fact that an unset variable will throw an E_NOTICE error, but one initialized as NULL will not.

The problem is, the set_error_handler and restore_error_handler calls can not be inside the function, which means you need 2 extra lines of code every time you are testing. And if you have any E_NOTICE errors caused by other code between the set_error_handler and restore_error_handler they will not be dealt with properly. One solution:

?>

Outputs:
True False
Notice: Undefined variable: j in filename.php on line 26

This will make the handler only handle var_exists, but it adds a lot of overhead. Everytime an E_NOTICE error happens, the file it originated from will be loaded into an array.

Источник

Заметка про NULL

Основные положения

Для удобства сделаем процедуру, печатающую состояние булевого параметра:

и включим опцию печати сообщений на консоль:

Привычные операторы сравнения пасуют перед NULLом:

Сравнение с NULLом

Соответственно, IS NOT NULL действует наоборот: вернёт истину, если значение операнда отлично от NULLа и ложь, если он является NULLом:

DECODE идёт против системы:

Пример с составными индексами находится в параграфе про индексы.

Логические операции и NULL

В большинстве случаев неизвестный результат обрабатывается как ЛОЖЬ :

Отрицание неизвестности даёт неизвестность:

Операторы IN и NOT IN

Для начала сделаем несколько предварительных действий. Для тестов создадим таблицу T с одним числовым столбцом A и четырьмя строками: 1, 2, 3 и NULL

Включим трассировку запроса (для этого надо обладать ролью PLUSTRACE ).
В листингах от трассировки оставлена только часть filter, чтобы показать, во что разворачиваются указанные в запросе условия.

Предварительные действия закончены, давайте теперь поработаем с операторами. Попробуем выбрать все записи, которые входят в набор (1, 2, NULL) :

Попробуем теперь с NOT IN :

Вообще ни одной записи! Давайте разберёмся, почему тройка не попала в результаты запроса. Посчитаем вручную фильтр, который применила СУБД, для случая A=3 :

Из-за особенностей трёхзначной логики NOT IN вообще не дружит с NULLами: как только NULL попал в условия отбора, данных не ждите.

NULL и пустая строка

Здесь Oracle отходит от стандарта ANSI SQL и провозглашает эквивалентность NULLа и пустой строки. Это, пожалуй, одна из наиболее спорных фич, которая время от времени рождает многостраничные обсуждения с переходом на личности, поливанием друг друга фекалиями и прочими непременными атрибутами жёстких споров. Судя по документации, Oracle и сам бы не прочь изменить эту ситуацию (там сказано, что хоть сейчас пустая строка и обрабатывается как NULL, в будущих релизах это может измениться), но на сегодняшний день под эту СУБД написано такое колоссальное количество кода, что взять и поменять поведение системы вряд ли реально. Тем более, говорить об этом они начали как минимум с седьмой версии СУБД (1992-1996 годы), а сейчас уже двенадцатая на подходе.

NULL и пустая строка эквивалентны:

непременный атрибут жёсткого спора:

Длина пустой строки не определена:

Сравнение с пустой строкой невозможно:

Критики подхода, предлагаемого Ораклом, говорят о том, что пустая строка не обязательно обозначает неизвестность. Например, менеджер по продажам заполняет карточку клиента. Он может указать его контактный телефон (555-123456), может указать, что он неизвестен (NULL), а может и указать, что контактный телефон отсутствует (пустая строка). С оракловым способом хранения пустых строк реализовать последний вариант будет проблемно. С точки зрения семантики довод правильный, но у меня на него всегда возникает вопрос, полного ответа на который я так и не получил: как менеджер введёт в поле «телефон» пустую строку и как он в дальнейшем отличит его от NULLа? Варианты, конечно, есть, но всё-таки…

Вообще-то, если говорить про PL/SQL, то где-то глубоко внутри его движка пустая строка и NULL различаются. Один из способов увидеть это связан с тем, что ассоциативные коллекции позволяют сохранить элемент с индексом » (пустая строка), но не позволяют сохранить элемент с индексом NULL:

Использовать такие финты ушами на практике не стоит. Во избежание проблем лучше усвоить правило из доки: пустая строка и NULL в оракле неразличимы.

Математика NULLа

Этот маленький абзац писался пятничным вечером под пиво, на фоне пятничного РЕН-ТВшного фильма. Переписывать его лень, уж извините.

Очевидно, что мы ничем не сможем помочь Коле: неизвестное количество любовников Маши до замужества сводит все расчёты к одному значению — неизвестно. Oracle, хоть и назвался оракулом, в этом вопросе уходит не дальше, чем участники битвы экстрасенсов: он даёт очевидные ответы только на очевидные вопросы. Хотя, надо признать, что Oracle гораздо честнее: в случае с Колей он не будет заниматься психоанализом и сразу скажет: «я не знаю»:

С конкатенацией дела обстоят по другому: вы можете добавить NULL к строке и это её не изменит. Такая вот политика двойных стандартов.

NULL и агрегатные функции

Таблица с данными. Используется ниже много раз:

Пустые значения игнорируются агрегатами:

Набор данных только из NULLов:

Пустой набор данных:

NULL в OLAP

Удобная фишка sqlplus: при выводе данных заменяет NULL на указанную строку:

Проверяем дуализм NULLа в многомерном кубе:

Источник

isset — Определяет, была ли установлена переменная значением отличным от NULL

Описание

Определяет, была ли установлена переменная значением отличным от NULL

Если были переданы несколько параметров, то isset() вернет TRUE только в том случае, если все параметры определены. Проверка происходит слева направо и заканчивается, как только будет встречена неопределенная переменная.

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

Возвращаемые значения

Список изменений

Примеры

Пример #1 Пример использования isset()

// В следующем примере мы используем var_dump для вывода
// значения, возвращаемого isset().

$a = «test» ;
$b = «anothertest» ;

Функция также работает с элементами массивов:

Пример #2 isset() и строковые индексы

Результат выполнения данного примера в PHP 5.3:

Результат выполнения данного примера в PHP 5.4:

Примечания

Замечание: Поскольку это языковая конструкция, а не функция, она не может вызываться при помощи переменных функций.

При использовании isset() на недоступных свойствах объекта, будет вызываться перегруженный метод __isset(), если он существует.

Смотрите также

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

ВерсияОписание
5.4.0