Null vs. False vs. 0 в PHP


146

Мені кажуть, що хороші розробники можуть помітити / використати різницю між Nullта Falseта 0та всіма іншими хорошими "нічого" сутностями.
Що це різниця, особливо в PHP? Чи має це щось спільне ===?


Насправді неможливо реально розібратися, коли те, що використовується. Я думаю, важливо, щоб ви були КОНСИСТЕНТНІ, коли використовуєте 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 означає "невідоме значення", яке відрізняється від "no value" або "неініціалізована змінна". Нічого плюс 1 - це 1, тоді як невідоме значення плюс одне - невідоме значення. Просто пам’ятайте, що будь-який оператор, застосований до null, повинен (повинен) призвести до нуля, тому що будь-яка операція з "невідомим значенням" призводить до невідомого значення.
Елі

7
майте на увазі, що це всі наміри . нічого спільного з тим, що відбувається насправді. насправді функція може повертати помилкове значення для неіснуючих значень (наприклад, 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, значення несуть значення, значення є формою документації.
e-satis

45

nullє null. falseєfalse . Сумно але правда.

в PHP не так багато послідовностей. розробники намагаються робити null означає "невідомий" або "неіснуючий". але часто False слугуватиме як "неіснуючий" (наприклад, strrpos ('fail', 'search') поверне помилкові, а не нульові)

ви часто будете бачити нуль, коли вони вже використовують false для чогось. наприклад filter_input (). Вони повертаються помилковими, якщо змінна не відповідає фільтру. і 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)

24
в моєму описі 0 == null - це абсолютна дурниця, оскільки 0 - це значення, а null - прапор, який показує, що змінна неініціалізована. Дякуємо команді php
mercsen

1
Ви двічі повторювали свій розділ коду, починаючи з var_dump( null == 0 );.
Sparky

2
що насправді дивно в php: null <-1 => ІСТИНА
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. Це повинно дати вам чітке розуміння.


5

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

Зараз у PHP ця якість значень зазвичай використовується при поверненні значення, яке іноді може бути 0(нуль), але іноді може статися, що функція не вдалася. У таких випадках у PHP ви повертаєтесь, falseі вам доведеться перевірити ці випадки за допомогою оператора ідентифікації ===. Наприклад, якщо ви шукаєте позицію однієї струни всередині іншої, і ви використовуєте strpos(), ця функція повертає числове положення, яке може бути 0, якщо рядок знайдено в самому початку, але якщо рядок не знайдено в все, тоді strpos()повернеться, falseі вам доведеться це враховувати, маючи справу з результатом.

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


5

Неправдиво, Нуль, Нічого, 0, Не визначено , etc., etc.

Кожен із них має конкретні значення, які співвідносяться з фактичними поняттями. Іноді кілька значень перевантажуються в одне ключове слово або значення.

В C і C ++ , NULL, Falseі 0перевантажені в той же значення. У C # вони 3 різних поняття.

nullабо NULLзазвичай вказує на відсутність значення, але зазвичай не вказується чому. 0вказує на натуральне число нуль і має еквівалентність типу 1, 2, 3 і т.д., а в мовах, які підтримують окремі поняття, NULLслід обробляти лише число.

Неправда вказує на неправду. І використовується в двійкових значеннях . Це не означає нестатість, а також не означає 0. Він просто вказує одне з двох двійкових значень.

Ніщо не може вказувати на те, що значення спеціально встановлено таким, що не має нічого, що вказує на те саме, що і null, але з наміром.

Не визначене в деяких мовах означає, що значення ще не встановлено, оскільки жоден код не вказав фактичне значення.


Цікаво, мабуть, але зовсім не обговорює 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?


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

Null використовується в базах даних для представлення "немає запису" або "немає інформації". Отже, у вас може бути поле, яке описує "чи хоче цей користувач нам надсилати електронні листи", де True означає, що вони це роблять, False означає, що вони нічого не хочуть надсилати, але Null означатиме, що ви цього не робите " я не знаю. Вони можуть відбуватися через зовнішні з'єднання тощо.

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

Тож особисто я завжди ініціалізую булеве значення FALSE, а ініціалізація однієї на NULL виглядала б трохи прискіпливою (навіть у С, де обидва лише 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 як тип першого класу на мові нормально, і я думаю, що Джоел говорив про це своєю недавньою поштою. Але намагайтеся не використовувати суміші та співставляти боли з вашими даними у своїх процедурах, і ви повинні бути прекрасно.


1

У PHP це залежить від того, чи ти перевіряєш типи:

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

Технічно нульовим є 0x00лише в PHP ( null == 0x00 ) && ( null !== 0x00 ).

0 - ціле значення.


1

Один цікавий факт, що стосується NULLPHP: Якщо ви встановили var, рівний NULL, він такий самий, як якщо б ви викликалиunset() .

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


0

Null - це нічого, False - це трохи, а 0 - це (мабуть) 32 біти.

Не експерт з PHP, але в деяких сучасних мовах вони не є взаємозамінними. Я начебто сумую за тим, що 0 і false є взаємозамінними, але, якщо булевий фактичний тип, ви можете мати методи та об'єкти, пов'язані з ним, так що це просто компроміс. Нуль, однак, недійсне, відсутність чогось по суті.


0

Ну, я не можу запам'ятати достатньо моїх днів PHP, щоб відповісти на частину "===", але для більшості мов C-стилю NULL слід використовувати в контексті значень покажчика, false як булева, а нуль як a числове значення, таке як int. '\ 0' - це звичайне значення для контексту символів. Зазвичай я також вважаю за краще використовувати 0,0 для поплавців та пар.

Отже .. швидка відповідь: контекст.


0

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

Потім, щоб більше ускладнити речі, у базах даних є поняття null, що означає відсутність або непридатність, і більшість мов не мають прямого способу зіставлення DBNull до їх нуля. Наприклад, донедавна, наприклад, не було різниці між int, який є null, і нулем, але це було змінено на nullible ints.

Вибачте, що цей звук ускладнився. Просто це вже протягом багатьох років є мовним стилем у мовах, і до останнього часу він ніде не мав чіткого дозволу. Люди звикли просто збивати речі разом або робити порожніми чи 0 представляють нулі в базі даних, що не завжди працює надто добре.


0

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

Іншими словами, 0 можна визначити як число, яке при додаванні до якогось натурального числа дає те саме число:

x + 0 = x

Аналогічно, False - це таке значення, що диз'юнкція його та будь-якого іншого значення є тим самим значенням:

x || False = x

Null - це концептуально щось зовсім інше. Залежно від мови, для неї існують різні семантики, але жодна з них не описує "початкове значення" як "False" і "0". Алгебри для Null немає. Він відноситься до змінних, як правило, означає, що змінна не має конкретного значення в поточному контексті. У більшості мов немає операцій, визначених у Null, і помилка використання Null як операнда. У деяких мовах є спеціальне значення, яке називається "нижнє", а не "null", яке є заповнювачем для значення обчислення, яке не закінчується.

Я писав докладніше про наслідки NULL в інших місцях.


1
offtopic, false == 0 повністю відстає. Тим більше, що PHP повертає дані АБО невдача функції. див. повернення для mysql_insert_id. "" "Ідентифікатор, сформований для стовпця AUTO_INCREMENT попереднім запитом на успіх, 0, якщо попередній запит не генерує значення AUTO_INCREMENT, або FALSE, якщо не встановлено з'єднання MySQL." "" В основному він може повернути A) ідентифікатор, Б) нуль, С) помилково ... тепер, якщо це перший пункт таблиці, id буде нульовим! тому всі три значення однакові! як розробник може зрозуміти три типи нулів? ... і я згоден з вашим дописом про null.
gcb

0

Хтось може пояснити мені, чому "NULL" - це не просто рядок у екземплярі порівняння?

$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!

1
Тому що PHP внутрішньо передає цілий тип і порівнює потім. php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0)див. php.net/manual/en/language.operators.comppare.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/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.