Jaka jest różnica między is_null ($ var) i ($ var === null)?

84

Czy jest jakaś różnica między tym ...

if (is_null($var)) {
    do_something();
}

i to?

if ($var === null) {
    do_something();
}

Która forma jest lepsza podczas sprawdzania, czy zmienna zawiera wartość null? Czy są jakieś skrajne przypadki, o których powinienem wiedzieć? (Inicjalizuję wszystkie moje zmienne, więc nieistniejące zmienne nie stanowią problemu).

kijin
źródło
6
Można by pomyśleć, że ===operator byłby szybszy, ponieważ nie jest to jawna funkcja ... ale raz czy dwa byłem zaskoczony.
John Giotta,

Odpowiedzi:

31

Pod warunkiem, że zmienna jest zainicjalizowana (co wskazałeś - chociaż nie jestem w 100% pewien, czy to ma znaczenie w tym kontekście, czy nie. Oba rozwiązania mogą generować ostrzeżenie, jeśli zmienna nie została zdefiniowana), funkcjonalnie są takie same. Przypuszczam, ===że byłby nieznacznie szybszy, ponieważ usuwa narzut wywołania funkcji.

To naprawdę zależy od tego, jak patrzysz na swój stan.

===służy do ścisłego porównania danych. NULL ma tylko jedną `` wartość '', więc działa to przy porównywaniu z NULL (która jest stałą PHP o wartości null)

is_null sprawdza, czy zmienna ma typ danych NULL.

Tak naprawdę to od Ciebie zależy, co wybierzesz.

Craige
źródło
2
Dziękuję za wyjaśnienie funkcji porównania według wartości i porównania według typu.
kijin
5
Wolę is_nullwariant, bo == nullzamiast niego łatwo go przypadkowo użyć === null. Ponieważ == nulljest to to samo, co empty(zobacz inną odpowiedź), wprowadza to większy potencjał błędu programisty (zwłaszcza młodszego i średniego poziomu) niż prosty i czytelny is_null.
ryanm
101

jest true

jest false

        | isset   | is_null | ===null | ==null  | empty   |
|-------|---------|---------|---------|---------|---------|
|  null |    ❌   |    ✅   |    ✅   |    ✅  |    ✅   |
|  true |    ✅   |    ❌   |    ❌   |    ❌  |    ❌   |
| false |    ✅   |    ❌   |    ❌   |    ✅  |    ✅   |
|     0 |    ✅   |    ❌   |    ❌   |    ✅  |    ✅   |
|     1 |    ✅   |    ❌   |    ❌   |    ❌  |    ❌   |
|    \0 |    ✅   |    ❌   |    ❌   |    ❌  |    ❌   |
| unset |    ❌   |    ✅   |    ✅   |    ✅  |    ✅   |
|   ""  |    ✅   |    ❌   |    ❌   |    ✅  |    ✅   |

Podsumowanie: 🔸 ♦ ️🔸

  • empty jest równa ==null
  • is_null jest równa ===null
  • issetjest odwrotnością is_nulli===null
PHPst
źródło
12
Naprawdę kocham ten stół.
Cheok Yan Cheng,
3
Może to sprawić, że stół nieco bardziej jasne mieć pierwszą kolumnę o nazwie $vreprezentować pewną zmienną rodzajowe, a potem inni isset($v), is_null($v), $v===nulli tak dalej
Brandin
@Brandin Dzięki za sugestię. Zapraszam do edycji odpowiedzi.
PHPst
4
@Pacerier Wyraźnie powiedział, że są równoważne, więc nie ma różnicy funkcjonalnej.
PHPst
1
issetnie będzie narzekać na niezdefiniowaną zmienną, zwróci false. Użycie is_nulllub === nullspowoduje powiadomienie.
user1431317
17

Oba są dokładnie takie same, używam, is_nullponieważ sprawia, że ​​mój kod jest bardziej czytelny

Ish
źródło
3
i chociaż === może być na początku szybszy, optymalizator PHP powinien temu zaradzić.
foo
10
Wydaje mi się, że is_nulljest mniej jasne. Chociaż może ładnie czytać, $v === nullnie pozostawia wątpliwości, że porównanie jest wykonywane przy użyciu ścisłej semantyki, ale is_null($v)niektórzy programiści będą się zastanawiać, czy używa, ===czy ==semantyki.
koza
4
@goat, ish1301, Ponadto is_nullmożna je całkowicie usunąć lub przedefiniować , ale === nullzawsze będzie działać.
Pacerier
@Pacerier, chociaż twój przykład jest interesujący, prawdopodobieństwo, że ktoś zainstaluje pakiet runkit pecl, a następnie skonfiguruje go tak, aby umożliwić usunięcie wbudowanych funkcji, a następnie usunięcie is_null, wszystkich rzeczy, bez zastępowania go czymś bardzo bliskim zera lub zerowym ty preferujesz. Jedyny scenariusz, jaki przychodzi mi do głowy, w którym osoba chciałaby usunąć is_null, to zmiana globalnego zachowania porównania zerowego. Na przykład; zwracanie false zamiast true dla nieustawionego; W tym przypadku byłoby to faktycznie możliwe tylko wtedy, gdyby kod był napisany z wartością is_null na początku.
kaan_a
7

Jeśli wydaje się, że tak wiele funkcji typu is_foo () wydaje się zbędne dla php, kiedy możesz po prostu użyć standardowych operatorów porównania, rozważ funkcje nazywane programowo.

$arrayOfNullValues = array_filter($myArray, 'is_null');
Koza
źródło
$arrayWithoutNullValuesbędzie przechowywać tablicę zawierającą tylko null wartości.
PointedEars
5

Właśnie przeprowadziłem szybki test porównawczy, testując milion iteracji każdego. is_nullzajęło 8 sekund; === nullwziął 1.

Tak więc połączenie z is_nullnumerem jest o 0,000007 s wolniejsze niż połączenie ===na moim komputerze.

Znalazłbym coś bardziej przydatnego do optymalizacji.


Mój kod:

<?php

$start = time();
$var = null;

for ($i = 1000000; $i--; ) {
    is_null($var);
}

echo time() - $start;

$start = time();

for ($i = 1000000; $i--; ) {
    $var === null;
}

echo time() - $start;
samotny dzień
źródło
1
Co ciekawe, wydaje się, że PHP / 7 rozwiązało ten problem i wydajność jest teraz prawie identyczna; w rzeczywistości is_null()jest nieco szybszy na moim komputerze pod 7.1.9 Win32.
Álvaro González
@ ÁlvaroGonzález Zauważyłem to samo. Różnica między tymi dwoma funkcjami jest pomijalna. (is_null: 0,54486592610677, === null: 0,7440135592506) przy 10000 operacji. Test był przeprowadzany 30 razy i te liczby są średnią.
Justin E
1

Za każdym razem korzystałbym z wbudowanej funkcji PHP zamiast porównania operatorów.

Michael Irigoyen
źródło
0

is_null($var)jest około 14 razy wolniejszy niż $var===null... 37,8 ms vs. 2,6 ms.

Ale właściwie nie wiem dlaczego.

Floern
źródło
0

Jedną rzeczą, o której ludzie często zapominają w tej dyskusji, jest to, że jeśli zależy ci na ścisłym sprawdzaniu typu, is_nullpomoże ci to nigdy nie popełniać literówki w operatorach porównania (== vs ===).

Ogier Schelvis
źródło