Нулевой против Ложного против 0 в PHP

146

Я сказал , что хорошие разработчики могут определить / использовать разницу между Nullи Falseи 0и всей другой хорошей «ничего» сущностью.
Что это разница, особенно в PHP? Это как-то связано ===?

stalepretzel
источник
Практически невозможно реально понять, когда что используется. Я думаю, важно, чтобы вы были последовательны, когда вы используете nullи когда false. Я предпочитаю использовать nullпри извлечении значения из метода, потому что я могу использовать , issetчтобы определить , будет ли возвращено значение вместо того , чтобы использовать , emptyкоторый не будет принимать во внимание: false, 0, '0'или пустая строка, которая может быть жизнеспособные ценности во многих ситуациях. Для меня это самое чистое решение в грязной конструкции.
JMRC

Ответы:

221

Это зависит от языка, но в PHP:

Nullозначает « ничего ». VAR не был инициализирован.

Falseозначает « не соответствует действительности в логическом контексте ». Используется, чтобы явно показать, что вы имеете дело с логическими проблемами.

0 является int . Ничего общего с остальным выше, используется для математики.

Хитрость заключается в том, что в динамических языках, таких как PHP, все они имеют значение в логическом контексте , который (в PHP)False .

Если вы проверяете его ==, он проверяет логическое значение, так что вы получите равенство. Если вы проверите это с=== , он проверит тип, и вы получите неравенство.

Так почему они полезны?

Ну, посмотри на strrpos()функцию. Он возвращает False, если ничего не нашел, но 0, если он нашел что-то в начале строки!

<?php
// pitfall :
if (strrpos("Hello World", "Hello")) { 
    // never exectuted
}

// smart move :
if (strrpos("Hello World", "Hello") !== False) {
    // that works !
}
?>

И конечно, если вы имеете дело с государствами:

Вы хотите сделать разницу между DebugMode = False(установлено на выключено), DebugMode = True(установлено на включено) и DebugMode = Null(не установлено вообще, приведет к сложной отладке ;-)).

е-удовлетворяться
источник
39
Примечание по поводу Null: PHP использует его как «нет значения», но это не очень хорошая привычка. В общем, Null означает «неизвестное значение», которое отличается от «нет значения» или «неинициализированная переменная». Ничто плюс 1 равно 1, а неизвестное значение плюс один - неизвестное значение. Просто помните, что любой оператор, примененный к null, будет (должен) приводить к null, потому что любая операция с «неизвестным значением» приводит к неизвестному значению.
Илай
7
Имейте в виду, что это все намерения . ничего общего с тем, что происходит на самом деле. в действительности функция может возвращать false для несуществующих значений (например, strpos, input_filter) и null для сбоя (например, input_filter). так что ответ, используйте === false и / или === null, после прочтения документации этой конкретной функции.
GCB
5
@Eli: откуда вы взяли, что Null вообще означает «неизвестное значение». Я не могу думать ни о каких компьютерных языках, где это правда, и при этом это не означает, что в английском языке, по крайней мере, не в соответствии с определением, которое я могу найти или услышал. Может быть, вы знаете что-то, чего я не знаю?
иконоборчество
2
@iconoclast - я беру это из мира баз данных. Насколько я понимаю, null используется в качестве заполнителя для значения данных, которого нет в базе данных или неизвестно. См. Dev.mysql.com/doc/refman/5.0/en/working-with-null.html или en.wikipedia.org/wiki/Null_%28SQL%29 .
Эли
2
Элай не ошибся. Он семантически заявляет, что когда вы используете null, вы сообщаете другим программистам, что не знаете, что там. Это не определено. Когда вы используете 0, вы сигнализируете, что знаете, что там: число. А вот цифры обозначают отсутствие вещей. Помните, что независимо от того, как значения в PHP-угрозах, значения имеют значение, значения являются формой документации.
е-удовлетворяться
45

nullесть null. falseявляетсяfalse . Грустно, но правда.

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

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

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)
GCB
источник
24
в моем мнении 0 == ноль - абсолютная ерунда, так как 0 - значение, а ноль - флаг, показывающий, что переменная неинициализирована. Спасибо команде php
mercsen
1
Вы дважды повторили свой раздел кода, начиная с var_dump( null == 0 );.
Sparky
2
что действительно странно в php: null <-1 => TRUE
thehpi
1
@mercsen По крайней мере, если бы PHP постоянно вел себя как 0 == null, я бы с этим согласился. Как ни странно, 0 == nullи null == [], но [] != 0!!
Nawfal
1
strrpos('fail', 'search') will return false, and not nullна мой взгляд, это правильно - если nullозначает неизвестное, то strrposвозвращение nullбудет похоже на то, что «я не знаю, есть ли строка», а не «нет строки».
Eborbob
22

Ниже приведен пример:

            Comparisons of $x with PHP functions

Expression          gettype()   empty()     is_null()   isset() boolean : if($x)
$x = "";            string      TRUE        FALSE       TRUE    FALSE
$x = null;          NULL        TRUE        TRUE        FALSE   FALSE
var $x;             NULL        TRUE        TRUE        FALSE   FALSE
$x is undefined     NULL        TRUE        TRUE        FALSE   FALSE
$x = array();       array       TRUE        FALSE       TRUE    FALSE
$x = false;         boolean     TRUE        FALSE       TRUE    FALSE
$x = true;          boolean     FALSE       FALSE       TRUE    TRUE
$x = 1;             integer     FALSE       FALSE       TRUE    TRUE
$x = 42;            integer     FALSE       FALSE       TRUE    TRUE
$x = 0;             integer     TRUE        FALSE       TRUE    FALSE
$x = -1;            integer     FALSE       FALSE       TRUE    TRUE
$x = "1";           string      FALSE       FALSE       TRUE    TRUE
$x = "0";           string      TRUE        FALSE       TRUE    FALSE
$x = "-1";          string      FALSE       FALSE       TRUE    TRUE
$x = "php";         string      FALSE       FALSE       TRUE    TRUE
$x = "true";        string      FALSE       FALSE       TRUE    TRUE
$x = "false";       string      FALSE       FALSE       TRUE    TRUE

Пожалуйста, посмотрите это для более подробной информации о сравнениях типов в PHP. Это должно дать вам четкое понимание.

KristCont
источник
5

В PHP вы можете использовать операторы === и! ==, чтобы проверить не только, равны ли значения, но и совпадают ли их типы. Так, например: 0 == falseесть true, но 0 === falseесть false. То же самое касается !=против !==. Также, если вы сравнитеnull с двумя другими, используя упомянутые операторы, ожидайте аналогичных результатов.

Теперь в PHP это качество значений обычно используется при возврате значения, которое иногда может быть 0(ноль), но иногда может случиться так, что функция потерпела неудачу. В таких случаях в PHP вы возвращаетесь, falseи вы должны проверить эти случаи с помощью оператора идентификации ===. Например, если вы ищете позицию одной строки внутри другой и используете strpos(), эта функция вернет числовую позицию, которая может быть 0, если строка найдена в самом начале, но если строка не найдена в все, затем strpos()вернется, falseи вы должны принять это во внимание при работе с результатом.

Если вы будете использовать ту же технику в своих функциях, любой, кто знаком со стандартной библиотекой PHP, поймет, что происходит и как проверить, является ли возвращаемое значение желаемым или произошла ли какая-то ошибка при обработке. То же самое на самом деле касается параметров функций, вы можете обрабатывать их по-разному в зависимости от того, являются ли они массивами или строками, или нет, и эта техника также широко используется во всем PHP, так что каждый получит ее довольно легко. Так что я думаю, что это сила.

inkredibl
источник
5

False, Null, Nothing, 0, Undefined и т. Д. И т. Д.

У каждого из них есть определенные значения, которые соотносятся с реальными понятиями. Иногда несколько значений перегружены в одно ключевое слово или значение.

В C и C ++ , NULL, Falseи 0перегружены в то же значение. В C # это 3 разных понятия.

nullили NULLобычно указывает на отсутствие ценности, но обычно не указывает, почему. 0указывает на натуральное число ноль и имеет эквивалентность типа 1, 2, 3 и т. д., а в языках, которые поддерживают отдельные понятия, NULLследует рассматривать только число.

Ложь указывает на неправду. И это используется в двоичных значениях . Это не значит unset и не значит 0. Это просто указывает на одно из двух двоичных значений.

Ничто не может указывать на то, что значение специально установлено как ничто, что указывает на то же самое, что и ноль, но с намерением.

Не определено в некоторых языках означает, что значение еще не установлено, потому что ни один код не указал фактическое значение.

Орион Адриан
источник
Интересно, возможно, но PHP вообще не обсуждается.
Брэд
4

Я просто впустую 1/2 день , пытаясь получить либо 0, null, falseчтобы вернуться из strops!

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

Концепт взять доменное имя, размещенное на сервере, и удостовериться, что это не корневой уровень, ОК, несколько разных способов сделать это, но я выбрал другой из-за других функций / конструкций php, которые я сделал.

Во всяком случае, здесь была основа изложения:

if (strpos($_SERVER ['SERVER_NAME'], dirBaseNAME ()) 
{ 
    do this 
} else {
    or that
}

{
echo strpos(mydomain.co.uk, mydomain);  

if ( strpos(mydomain, xmas) == null ) 
    {
        echo "\n1 is null"; 
    }

if ( (strpos(mydomain.co.uk, mydomain)) == 0 ) 
    {
        echo "\n2 is 0"; 
    } else {
        echo "\n2 Something is WRONG"; 
    }

if ( (mydomain.co.uk, mydomain)) != 0 ) 
    {
        echo "\n3 is 0"; 
    } else {
        echo "\n3 it is not 0"; 
    }

if ( (mydomain.co.uk, mydomain)) == null ) 
    {
        echo "\n4 is null"; 
    } else {
        echo "\n4 Something is WRONG"; 
    }
}

НАКОНЕЦ, прочитав эту тему, я обнаружил, что это работает !!!

{
if ((mydomain.co.uk, mydomain)) !== false ) 
    {
        echo "\n5 is True"; 
    } else {
        echo "\n5 is False"; 
    }
}

Спасибо за эту статью, теперь я понимаю, что, хотя это Рождество, это может быть и не Рождество false, как это может быть и NULLдень!

Потратив день на отладку некоторого простого кода, хотелось бы, чтобы я знал это раньше, так как я смог бы выявить проблему, а не пытаться заставить ее работать. Это не сработало, как False, NULLи 0не все так же, как True or False or NULL?

madesignUK
источник
2

Из онлайновой документации PHP :

Чтобы явно преобразовать значение в логическое значение, используйте приведение (bool) или (boolean).
Однако в большинстве случаев приведение не является необходимым, поскольку значение будет автоматически преобразовано, если для оператора, функции или структуры управления требуется логический аргумент.
При преобразовании в логическое значение следующие значения считаются ЛОЖНЫМИ:

  • логическое значение FALSE сам
  • целое число `` 0 (ноль)
  • поплавок 0.0 (ноль)
  • пустая строка и строка "0"
  • массив с нулевыми элементами
  • объект с нулевыми переменными-членами (только PHP 4)
  • особый тип NULL (включая неустановленные переменные)
  • Объекты SimpleXML, созданные из пустых тегов.
    Рассматривается TRUEлюбое другое значение (включая любой ресурс).

Так что, в большинстве случаев, это то же самое.

С другой стороны, ===и ==не одно и то же. Обычно вам просто нужен оператор "равно". Чтобы уточнить:

$a == $b    //Equal. TRUE if $a is equal to $b.
$a === $b   //Identical. TRUE if $a is equal to $b, and they are of the same type. 

Для получения дополнительной информации посетите страницу « Операторы сравнения » в онлайн-документации PHP.

Надеюсь это поможет.

Хавьер Констанцо
источник
1

Различия между этими значениями всегда сводятся к подробным языковым правилам. То, что вы изучаете для PHP, не обязательно верно для Python, или Perl, или C, и т. Д. Хотя важно изучить правила для языков, с которыми вы работаете, слишком полагаться на них - значит создавать проблемы , Проблема возникает, когда следующий программист должен поддерживать ваш код, и вы использовали некоторую конструкцию, которая использует некоторые мелкие детали Null vs. False (например). Ваш код должен выглядеть правильно (и наоборот, неправильный код должен выглядеть неправильно ).

Грег Хьюгилл
источник
1

Нуль используется в базах данных для представления «нет записи» или «нет информации». Таким образом, у вас может быть битовое поле, которое описывает «хочет ли этот пользователь отправлять нам электронные письма», где True означает, что он делает, False означает, что они не хотят ничего отправлять, но Null будет означать, что вы не я знаю Они могут появиться через внешние соединения и тому подобное.

Логическое значение Null часто различается - в некоторых языках NULL не равно ничему, поэтому if (a == NULL) всегда будет ложным.

Поэтому лично я всегда инициализирую логическое значение FALSE, а инициализация его значением NULL будет выглядеть немного странно (даже в C, где оба значения равны 0 ... просто стиль).

Питер
источник
1

Я думаю, что плохие разработчики находят в коде различные варианты использования null / 0 / false.

Например, одна из самых распространенных ошибок, которые делают разработчики, - возвращать код ошибки в виде данных с функцией.

// On error GetChar returns -1
int GetChar()

Это пример сахарного интерфейса. Это объясняется в книге «Отладка процесса разработки программного обеспечения», а также в другой книге «Написание правильного кода».

Проблема с этим, подразумевается или предположения, сделанные на тип char. На некоторых компиляторах тип char может быть без знака. Таким образом, даже если вы вернете -1, компилятор может вернуть 1. Подобные предположения компилятора в C ++ или C трудно обнаружить.

Вместо этого лучший способ - не смешивать код ошибки с вашими данными. Итак, следующая функция.

char GetChar()

сейчас становится

// On success return 1
// on failure return 0
bool GetChar(int &char)

Это означает, что независимо от того, насколько молод разработчик в вашем магазине разработки, он или она никогда не поймут это неправильно. Хотя речь не идет о избыточности или зависимости в коде.

Так что в целом, замена bool как первого типа класса в языке - это нормально, и я думаю, что Джоэл говорил об этом в своей недавней публикации. Но старайтесь не использовать смешивание и сопоставление bools с вашими данными в ваших подпрограммах, и вы должны быть в порядке.

Чад
источник
1

В PHP это зависит от того, проверяете ли вы типы:

( 
 ( false !== 0 ) && ( false !== -1 ) && ( false == 0 ) && ( false == -1 ) &&
 ( false !== null ) && ( false == null ) 
)

Технически ноль есть, 0x00но в PHP( null == 0x00 ) && ( null !== 0x00 ) .

0 является целочисленным значением

Гэвин М. Рой
источник
1

Один интересный факт NULLв PHP: если вы установите переменную равной NULL, она будет такой же, как если бы вы вызывали unset()ее.

NULLпо существу, означает, что переменной не присвоено значение; falseявляется допустимым Логическое значение, 0является допустимым целым значением, и PHP имеет некоторые довольно уродливые преобразования между 0, "0", ""и false.

dirtside
источник
0

Null - это ничто, False - немного, а 0 - (вероятно) 32 бита.

Не эксперт по PHP, но в некоторых более современных языках они не являются взаимозаменяемыми. Я как бы скучаю по тому, что 0 и false взаимозаменяемы, но с логическим значением, являющимся фактическим типом, вы можете иметь методы и объекты, связанные с ним, так что это просто компромисс. Нуль, тем не менее, отсутствие чего-либо по сути.

CodeRedick
источник
0

Ну, я не помню достаточно из моих дней PHP, чтобы ответить на часть "===", но для большинства языков стиля C, NULL должен использоваться в контексте значений указателя, false в качестве логического значения и ноль в качестве числовое значение, например, int. «\ 0» - это обычное значение для контекста символа. Я также обычно предпочитаю использовать 0.0 для чисел с плавающей и двойной.

Итак ... быстрый ответ: контекст.

jasonmray
источник
0

Практически во всех современных языках ноль логически относится к указателям (или ссылкам), не имеющим значения, или к переменной, которая не инициализирована. 0 - целочисленное значение нуля, а false - логическое значение, ну, в общем, false. Чтобы усложнить задачу, в C, например, null, 0 и false представлены одинаково. Я не знаю, как это работает в PHP.

Затем, чтобы еще больше усложнить задачу, в базах данных есть концепция нуля, что означает отсутствие или неприменимость, и большинство языков не имеют прямого способа сопоставить DBNull со своим нулем. Например, до недавнего времени не было никакого различия между int равным нулю и нулем, но это было изменено с помощью null-значений.

Извините, что усложнил этот звук. Просто в течение многих лет это было серьезной проблемой в языках, и до недавнего времени нигде не было четкого разрешения. Раньше люди просто собирали вещи вместе или делали пустыми, или 0 представляли собой нулевые значения в базе данных, что не всегда работает слишком хорошо.

Чарльз Грэм
источник
0

Ложь и 0 концептуально похожи, то есть они изоморфны. 0 - начальное значение для алгебры натуральных чисел, а False - начальное значение для булевой алгебры.

Другими словами, 0 может быть определено как число, которое при добавлении к некоторому натуральному числу дает это же число:

x + 0 = x

Аналогично, False - это значение, такое, что дизъюнкция его и любого другого значения является тем же значением:

x || False = x

Нулевой концептуально что-то совершенно другое. В зависимости от языка, для него существует разная семантика, но ни одна из них не описывает «начальное значение» как False и 0. Для Null нет алгебры. Он относится к переменным, обычно для обозначения того, что переменная не имеет конкретного значения в текущем контексте. В большинстве языков нет операций, определенных для Null, и использование Null в качестве операнда является ошибкой. В некоторых языках существует специальное значение, называемое «bottom», а не «null», которое является заполнителем для значения вычисления, которое не заканчивается.

Я написал более подробно о значении NULL в другом месте.

Apocalisp
источник
1
offtopic, false == 0 полностью запаздывает. Тем более, что php возвращает данные ИЛИ сбой в функции. смотрите возвращение для mysql_insert_id. "" "Идентификатор, сгенерированный для столбца AUTO_INCREMENT предыдущим запросом в случае успеха, 0, если предыдущий запрос не генерирует значение AUTO_INCREMENT, или FALSE, если не установлено соединение MySQL." "" В основном он может вернуть A) идентификатор, B) ноль, C) ложь ... теперь, если это первый элемент в таблице, id будет нулевым! так что все три значения одинаковы! Как разработчик может понять три типа нулей? ... и я согласен с вашим постом на ноль.
GCB
0

Кто-нибудь может объяснить мне, почему 'NULL' не просто строка в экземпляре сравнения?

$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!
vladzur
источник
1
Потому что PHP внутренне приводит к целочисленному типу и сравнивает потом. php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0)см. php.net/manual/en/language.operators.comparison.php Перевести строки и ресурсы в числа, обычная математика
Севиль,
-1

Проблемы с ложностью происходят из истории PHP. Проблема нацелена на плохо определенный скалярный тип.

'*' == true -> true (string match)
'*' === true -> false (numberic match)

(int)'*' == true -> false
(string)'*' == true -> true

Строгость PHP7 - это шаг вперед, но, возможно, этого недостаточно. https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/

Адриан
источник