Php null

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


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

Специальное значение NULL представляет собой переменную без значения. NULL — это единственно возможное значение типа null. Переменная считается null, если:

  • ей была присвоена константа NULL.
  • ей еще не было присвоено никакого значения.
  • она была удалена с помощью unset().

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

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

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

  $a = null;  $a + 1; // int(1)  $a - 1; // int(-1)  $a * 1; // int(0)  1 / $a; // bool(false)   

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

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

  // Правильная проверка переменной на null  $a = null;  is_null($a); // bool(true)  $a === null; // bool(true)   

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

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

   
// В if-выражениях null приводится к false, как и все другие ложные значения if($a) { echo 'Sure, $a is not null!'; } else { echo 'Mabye $a is null.' } // Проверка на empty() вернёт true, но не гарантирует, что проверяемая переменная - именно null $a = null; empty($a); // bool(true) $a = []; empty($a); // bool(true) $a = ''; empty($a); // bool(true) $a = 0; empty($a); // bool(true) $a = false; empty($a); // bool(true) // Проверка isset() вернёт false не только для null, но для не определённой переменной $a = null; isset($a); // bool(false) isset($undefined); // bool(false)

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

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

  // PHP уверен, что две неизвестности равны, и даже тождественно равны  $a = null; $b = null;  $a == $b; // bool(true)  $a === $b; // bool(true)   

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

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

   
// Для всех ложных значений гибкое сравнение с null возвращает true, кроме строки '0' $a = []; $a == null; // bool(true) $a = ''; $a == null; // bool(true) $a = 0; $a == null; // bool(true) $a = false; $a == null; // bool(true) // А при сравнении null со строкой '0' мы получим false, хотя null == false и '0' == false $a = '0'; $a == null; // bool(false) // Для всех неложных значений такое сравнение так же вернёт false $a = 1; $a == null; // bool(false) $a = '1'; $a == null; // bool(false)

Сравнение с null с помощью >, <, >=, <=, сравнение с отрицательными числами и другие заковырки

Не мне судить, насколько это является очевидным, но при сравнении с числами null всегда оказывается меньше них. Смотрите сами:

  // Не смотря на то, что null == 0, он оказывается меньше любого числа  null <= -1 // bool(true)  null <= 0 // bool(true)  null <= 1 // bool(true)  !(null >= -1) // bool(true)  null >= 0 // bool(true)  !(null >= 1) // bool(true)   

На вид ничего особенного, но из этого следует, что если в дело вмешивается null, может пройти бессмысленная, на первый взгляд, проверка:

  // Из-за подобного поведения я словил однажды баг, из-за которого почти поверил в магию :)  $a = null;  if($a <= -1 && $a >= 0) {   echo '$a <= -1 and $a >= 0 at the same time!';  }       

Разное поведение null в PHP, SQL и JavaScript

А вот это, на мой взгляд, самое скверное. Реализуя логику работы с ячейками баз данных, в которых разрешено значение null, на разных этапах продвижения данных от сервера к пользователю (например, MySQL -> PHP -> JavaScript) поведение null может меняться.

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

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

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

Вообще-то, не стоило читать этот пост. Держать в голове все эти нюансы, которые разные платформы трактуют по-разному, — неблагодарное занятие. Для того, чтобы избежать проблем с null нужно запомнить всего лишь одно правило:


Старайтесь не выполнять с null никаких лишних действий: не нужно его ни с чем сравнивать, складывать, сортировать. Там, где чисто теоретически переменная с null может просочиться в какие-то операторы, лучшим решением будет сперва проверить её функцией is_null().

mithrandir.ru

 $var = NULL; 

Что здесь случилось?

Простой: значение null было присвоено $var .

Да, значение null – это значение. Регулярное, нормальное значение. null не является логическим, а не числом, а не чем-либо еще. null
имеет тип null , который может принимать только одно возможное значение: null . null обычно используется в качестве значения-заполнителя для обозначения «нет значения». Но null – это просто нормальное значение и тип сам по себе. Здесь ничего не видно, двигайтесь вперед.

 for ($i = 0; $arr[$i] = NULL; $i++) { }    

Здесь null присваивается $arr[$i] на первой итерации. Выражение присваивания затем возвращает назначенное значение, т. Е. ($arr[$i] = NULL) оценивает значение null . Затем цикл for вычисляет этот null чтобы решить, следует ли продолжать или нет, и поскольку значение null
считается равным false , оно останавливается. Результатом этого цикла является:

 array(1) { [0]=> NULL } 

Т.е. массив, первым и единственным индексом которого является значение null . Ни больше ни меньше.

.
воение NULL имеет значение TRUE.

Это ваше единственное непонимание. Результатом выражения присваивания является назначенное значение . true . Вот почему это работает:

 $a = $b = $c;    

$a присваивается результат $b = $c , который равен $c .

Во всех этих примерах вы можете заменить null на false для того же самого эффекта.

ruphp.com

To extend a bit on tbdavis's comment:

:: NULL == NULL is true
:: NULL == FALSE is true
:: NULL == TRUE is false

However: note the implicit type conversions that PHP performs! When using 'identical' instead of 'equal' then both NULL === FALSE and NULL === TRUE yield FALSE. An overview is easily created using something like

   function evalExpr( $desc )
   {
     echo str_pad($desc , 15) . "--> ";
     var_dump( eval( "return(" . $desc . ");" ));
   }

Note that even TRUE AND TRUE does not evaluate to a boolean value, and that OR and XOR behave different as well!

   PHP Version: 4.0.6

   false          --> bool(false)
   true          --> bool(true)
   null          --> NULL
   !null          --> bool(true)

   true and true  --> int(1)
   true and false --> int(0)
   true or true  --> int(1)
   true or false  --> int(1)
   true xor true  --> bool(false)
   true xor false --> bool(true)
 
   true == null  --> bool(false)
   true === null  --> bool(false)
   true != null  --> bool(true)
   true !== null  --> bool(true)

   false == null  --> bool(true)
   false === null --> bool(false)
   false != null  --> bool(false)
   false !== null --> bool(true)

   null == null  --> bool(true)
   null != null  --> bool(false)
   null === null  --> bool(true)
   null !== null  --> bool(false)

   null or null  --> int(0)
   null xor null  --> bool(false)
   null and null  --> int(0)
 
   true or null  --> int(1)
   true xor null  --> bool(true)
   true and null  --> int(0)

   false or null  --> int(0)
   false xor null --> bool(false)
   false and null --> int(0)

   true < null    --> bool(false)
   true > null    --> bool(true)
   false < null  --> bool(false)
   false > null  --> bool(false)

   1 + null      --> int(1)
   "text" . null  --> string(4) "text"

Finally, for those who do not know SQL: in SQL the NULL value is evaluated a bit like "I do not know; it could be anything, like 0, 1, a, b, true, false or even nothing at all". This implies that in SQL NULL == NULL could be interpreted as "could be anything" == "could be something else", which does not yield true! Instead, it yields NULL, which boils down to FALSE in boolean context...

Likewise, in SQL:

   NULL AND TRUE yields NULL
   NULL OR TRUE yields TRUE
   NULL AND FALSE yields FALSE
   NULL OR FALSE yields NULL
   NULL == TRUE yields FALSE
   NULL == FALSE yields FALSE

a.

php.svchat.ru

nullnull. falsefalse. Грустно, но это правда.

в PHP не так много согласованности. разработчики TRY, чтобы сделать null, означает «unkown» или «несуществующий». но часто False будет служить «несуществующим» (например, strrpos ( «fail», «search» ) вернет false, а не null)

вы часто увидите, что null используется, когда они уже используют false для чего-то. например filter_input(). Они возвращают false, если переменная не работает с фильтром. и null, если переменная не существует (не существует означает, что она также не сработала с фильтром, поэтому зачем даже возвращать null?!?)

php имеет удобство возврата данных в функции. и из-за того, что разработчики записывают все виды отказа, а не данные.

И в PHP нет здравого смысла для обнаружения данных (int, str и т.д.) из отказа (false, null)

вы в значительной степени должны всегда тестировать === null или === false, в зависимости от функции. или для обоих, в таких случаях, как filter_input()/filter_var()

и здесь немного удовольствия от жонглирования типа. даже не включая массивы и объекты.

var_dump( 0<0 ); #bool(false) var_dump( 1<0 ); #bool(false) var_dump( -1<0 ); #bool(true) var_dump( false<0 ); #bool(false) var_dump( null<0 ); #bool(false) var_dump( ''<0 ); #bool(false) var_dump( 'a'<0 ); #bool(false) echo "n"; var_dump( !0 ); #bool(true) var_dump( !1 ); #bool(false) var_dump( !-1 ); #bool(false) var_dump( !false ); #bool(true) var_dump( !null ); #bool(true) var_dump( !'' ); #bool(true) var_dump( !'a' ); #bool(false) echo "n"; var_dump( false == 0 ); #bool(true) var_dump( false == 1 ); #bool(false) var_dump( false == -1 ); #bool(false) var_dump( false == false ); #bool(true) var_dump( false == null ); #bool(true) var_dump( false == '' ); #bool(true) var_dump( false == 'a' ); #bool(false) echo "n"; var_dump( null == 0 ); #bool(true) var_dump( null == 1 ); #bool(false) var_dump( null == -1 ); #bool(false) var_dump( null == false ); #bool(true) var_dump( null == null ); #bool(true) var_dump( null == '' ); #bool(true) var_dump( null == 'a' ); #bool(false) echo "n"; $a=0; var_dump( empty($a) ); #bool(true) $a=1; var_dump( empty($a) ); #bool(false) $a=-1; var_dump( empty($a) ); #bool(false) $a=false; var_dump( empty($a) ); #bool(true) $a=null; var_dump( empty($a) ); #bool(true) $a=''; var_dump( empty($a) ); #bool(true) $a='a'; var_dump( empty($a)); # bool(false) echo "n"; #new block suggested by @thehpi var_dump( null < -1 ); #bool(true) var_dump( null < 0 ); #bool(false) var_dump( null < 1 ); #bool(true) var_dump( -1 > true ); #bool(false) var_dump( 0 > true ); #bool(false) var_dump( 1 > true ); #bool(true) var_dump( -1 > false ); #bool(true) var_dump( 0 > false ); #bool(false) var_dump( 1 > true ); #bool(true) 

qaru.site


You May Also Like

About the Author: admind

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Adblock
detector