Najlepszy sposób na sprawdzenie istnienia zmiennej w PHP; isset () jest wyraźnie uszkodzony

187

Z isset()dokumentów :

isset() will return FALSE if testing a variable that has been set to NULL.

Zasadniczo isset()nie sprawdza, czy zmienna jest w ogóle ustawiona, ale czy jest ustawiona na cokolwiek innego NULL.

Biorąc to pod uwagę, jaki jest najlepszy sposób sprawdzenia istnienia zmiennej? Próbowałem czegoś takiego:

if(isset($v) || @is_null($v))

( @jest to konieczne, aby uniknąć ostrzeżenia, gdy $vnie jest ustawione), ale is_null()ma podobny problem jak isset(): zwraca TRUEzmienne nieustawione! Wydaje się również, że:

@($v === NULL)

działa dokładnie tak @is_null($v), więc to też nie działa .

Jak mamy rzetelnie sprawdzać istnienie zmiennej w PHP?


Edycja: w PHP istnieje wyraźna różnica między zmiennymi, które nie są ustawione, a zmiennymi, które są ustawione na NULL:

<?php
$a = array('b' => NULL);
var_dump($a);

PHP pokazuje, że $a['b']istnieje i ma NULLwartość. Jeśli dodasz:

var_dump(isset($a['b']));
var_dump(isset($a['c']));

widać niejednoznaczność, o której mówię z isset()funkcją. Oto wynik wszystkich trzech z nich var_dump()s:

array(1) {
  ["b"]=>
  NULL
}
bool(false)
bool(false)

Dalsza edycja: dwie rzeczy.

Po pierwsze, przypadek użycia. Tablica jest przekształcana w dane UPDATEinstrukcji SQL , gdzie klucze tablicy są kolumnami tabeli, a wartości tablicy są wartościami, które należy zastosować do każdej kolumny. Każda kolumna tabeli może zawierać NULLwartość, oznaczoną przez przekazanie NULLwartości do tablicy. Państwo potrzebuje sposobu na odróżnienie klucza tablicy nie istniejącą, a wartość tablicy jest ustawiany na NULL; to jest różnica między nie aktualizowaniem wartości kolumny a aktualizowaniem wartości kolumny do NULL.

Po drugie, odpowiedź Zoredache za , array_key_exists()działa poprawnie na moim powyższym przypadku użycia i wszelkich zmiennych globalnych:

<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));

wyjścia:

bool(true)
bool(false)

Ponieważ to właściwie obsługuje prawie wszędzie, widzę, że istnieje jakakolwiek dwuznaczność między zmiennymi, które nie istnieją, a zmiennymi ustawionymi NULL, dlatego nazywam array_key_exists()oficjalny najprostszy sposób w PHP, aby naprawdę sprawdzić istnienie zmiennej .

(Jedyny inny przypadek, jaki mogę wymyślić, dotyczy właściwości klasy, dla których istnieje property_exists(), zgodnie z jego dokumentacją , działa podobnie do array_key_exists()tego, że właściwie rozróżnia brak ustawienia i ustawienie NULL).

chazomaticus
źródło
Nie możesz sprawdzić - ale dlaczego musisz?
za dużo php
12
NULL ma bardzo specyficzne znaczenie w PHP i jest to całkowicie odrębna koncepcja od tego, czy zmienna jest ustawiona czy nie.
chazomaticus
33
Istnieją powody, aby rozróżniać między wartością zerową a nieistniejącą. Na przykład budujesz obiekt do reprezentowania wiersza w tabeli bazy danych. Dla każdej kolumny w rzędzie tworzysz zmienną prywatną, dostępną tylko za pomocą metody getter obiektu. Załóżmy, że wartość kolumny jest pusta. Skąd ta metoda pobierająca wie, czy nie ma takiej kolumny w tabeli, czy też ten obiekt ma tam po prostu wartość zerową? Na szczęście w moim przypadku zmienna prywatna jest tak naprawdę wpisem w prywatnej tablicy, więc mogę użyć tablicy_klucz_istniejący, ale to jest prawdziwy problem.
Nathan Long
1
Tak, został usunięty z nowych wersji PHP. Niestety nie zniknął z każdego wdrożenia PHP. Wydaje się też, że bezcelowe szczegóły semantyczne spierają się o to, czy mówimy o elementach tablicy, czy o zmiennych. Niezależnie od standardów, które według Ciebie powinien spełniać kod, warto wiedzieć, jak obejść niespójność w języku PHP.
chazomaticus
2
@chazomaticus Ale zmienne i elementy tablicy są zasadniczo różnymi rzeczami ; to, że możesz robić z nimi te same rzeczy, nie oznacza, że ​​są lub powinny być w 100% zamienne. Nie ma tutaj „niespójności w języku PHP”, po prostu coś, czego nie lubisz / nie rozumiesz. Jeśli chodzi o to register_globals, wciąż mam problem z sytuacją, w której nawet to wymagałoby takiego rozróżnienia, ponieważ wszystko zarejestrowane z żądania HTTP zawsze byłoby ciągiem, a nie ciągiem null.
IMSoP

Odpowiedzi:

97

Jeśli sprawdzana zmienna byłaby w zasięgu globalnym, możesz:

array_key_exists('v', $GLOBALS) 
Zoredache
źródło
3
Ach ha! TERAZ mówisz! Jak zrobiłbyś to dla, powiedzmy, właściwości klasy?
chazomaticus
22
Jako wariant, jeśli sprawdzenie musi działać również dla zmiennych zasięgu lokalnego, można wykonać a, $defined_vars = get_defined_vars();a następnie przetestować za pomocą array_key_exists('v', $defined_vars);.
Henrik Opel
1
To wydaje mi się trochę brzydkie, ale w przypadku, gdy faktycznie sprawdzasz element tablicy, ma to o wiele większy sens: isset($foo[$bar])staje sięarray_key_exists($bar, $foo)
Arild
property_existswydaje się obiecujące, z wyjątkiem tego:> Funkcja property_exists () nie może wykryć właściwości, które są magicznie dostępne przy użyciu metody magicznej __get.
aleww
@alexw Zmienne „utworzone” przez __get rzeczywiście nie istnieją. __get to dowolny kod używany jako rezerwowy dla nieistniejących zmiennych, który może zwrócić cokolwiek chce, bez względu na to, czy jakieś istotne dane zostały kiedykolwiek zapisane.
Brilliand
46

Próba przedstawienia przeglądu różnych dyskusji i odpowiedzi:

Nie ma jednej odpowiedzi na pytanie, która zastąpiłaby wszystkie issetmożliwe sposoby . Niektóre przypadki użycia są rozwiązywane przez inne funkcje, podczas gdy inne nie poddają się kontroli lub mają wątpliwą wartość poza kodowaniem. Inne przypadki użycia nie są „zepsute” ani „niespójne”, ale pokazują, dlaczego issetreakcja na nie nulljest logicznym zachowaniem.

Rzeczywiste przypadki użycia (z rozwiązaniami)

1. Klucze tablic

Tablice mogą być traktowane jak zbiory zmiennych, ze unseti issettraktując je tak, jakby były. Ponieważ jednak można je powtarzać, zliczać itp., Brakująca wartość nie jest taka sama jak wartość, której wartość jest null.

Odpowiedzią w tym przypadku jest użycie array_key_exists()zamiastisset() .

Ponieważ wymaga to sprawdzenia tablicy jako argumentu funkcji, PHP nadal będzie generować „powiadomienia”, jeśli sama tablica nie istnieje. W niektórych przypadkach można zasadnie argumentować, że każdy wymiar powinien zostać zainicjowany jako pierwszy, więc zawiadomienie wykonuje swoją pracę. W innych przypadkach array_key_existsfunkcja „rekurencyjna” , która z kolei sprawdza każdy wymiar tablicy, unikałaby tego, ale zasadniczo byłaby taka sama jak @array_key_exists. Jest to również nieco styczne do obsługi nullwartości.

2. Właściwości obiektu

W tradycyjnej teorii programowania obiektowego enkapsulacja i polimorfizm są kluczowymi właściwościami obiektów; w implementacji klasy oparte OOP jak PHP, kapsułkowane właściwości są zadeklarowane jako część definicji klasy, a biorąc pod uwagę poziomy dostępu ( public, protected, lub private).

Jednak PHP pozwala również dynamicznie dodawać właściwości do obiektu, tak jak klucze do tablicy, a niektórzy ludzie używają obiektów bezklasowych (technicznie instancji wbudowanej stdClass, która nie ma metod ani funkcji prywatnej) w podobny sposób droga do tablic asocjacyjnych. Prowadzi to do sytuacji, w których funkcja może chcieć wiedzieć, czy dana właściwość została dodana do danego obiektu.

Podobnie jak w przypadku kluczy tablic, w języku znajduje się rozwiązanie do sprawdzania właściwości obiektu, zwane, w miarę rozsądnym,property_exists .

Przypadki użycia, których nie można uzasadnić, z dyskusją

3. register_globalsi inne zanieczyszczenia globalnej przestrzeni nazw

register_globalsFunkcja dodana do zakresu zmiennych globalnych, których nazwiska zostały określone przez aspektów żądania HTTP (GET i POST parametrów i ciasteczka). Może to prowadzić do błędnego i niepewnego kodu, dlatego został domyślnie wyłączony od wersji PHP 4.2 wydanej w sierpniu 2000 r. I całkowicie usunięty w wersji PHP 5.4 wydanej w marcu 2012 r . Możliwe jest jednak, że niektóre systemy nadal działają z włączoną lub emulowaną tą funkcją. Możliwe jest również „zanieczyszczenie” globalnej przestrzeni nazw na inne sposoby, za pomocą globalsłowa kluczowego lub $GLOBALStablicy.

Po pierwsze, register_globalsjest mało prawdopodobne , że sama nieoczekiwanie wytworzy nullzmienną, ponieważ wartości GET, POST i cookie zawsze będą ciągami znaków (z ''ciągle wracającymi truez isset), a zmienne w sesji powinny być całkowicie pod kontrolą programisty.

Po drugie, zanieczyszczenie zmiennej o wartości nullstanowi problem tylko wtedy, gdy spowoduje to nadpisanie niektórych wcześniejszych inicjalizacji. „Nadpisywanie” niezainicjowanej zmiennej nullbyłoby problematyczne, gdyby kod gdzieś indziej rozróżniał oba te stany, więc sama ta możliwość stanowi argument przeciwko takiemu rozróżnieniu.

4. get_defined_varsicompact

Kilka rzadko używanych funkcji w PHP, takich jak get_defined_varsi compact, pozwala traktować nazwy zmiennych tak, jakby były kluczami w tablicy. W przypadku zmiennych globalnych tablica superglobalna$GLOBALS umożliwia podobny dostęp i jest bardziej powszechna. Te metody dostępu będą zachowywać się inaczej, jeśli zmienna nie zostanie zdefiniowana w odpowiednim zakresie.

Gdy zdecydujesz się traktować zestaw zmiennych jako tablicę za pomocą jednego z tych mechanizmów, możesz wykonać na nim wszystkie te same operacje, co na dowolnej normalnej tablicy. W związku z tym patrz 1.

Funkcjonalność, która istniała tylko po to, by przewidzieć, jak te funkcje będą się zachowywać (np. „Czy w tablicy zwróci się klucz„ foo ” get_defined_vars?)) Jest zbędna, ponieważ można po prostu uruchomić tę funkcję i dowiedzieć się bez żadnych niepożądanych efektów.

4a Zmienne zmienne ( $$foo)

Chociaż nie do końca takie same, jak funkcje, które zamieniają zestaw zmiennych w tablicę asocjacyjną, większość przypadków wykorzystujących „zmienne zmienne” („przypisanie do zmiennej nazwanej na podstawie tej innej zmiennej”) może i powinna zostać zmieniona, aby zamiast tego użyć tablicy asocjacyjnej .

Zasadniczo nazwa zmiennej jest etykietą nadaną wartości przez programistę; jeśli określasz to w czasie wykonywania, tak naprawdę nie jest to etykieta, ale klucz w sklepie z kluczowymi wartościami. Praktycznie, nieużywając tablicy, tracisz zdolność liczenia, iterowania itp .; może również okazać się niemożliwe posiadanie zmiennej „poza” składnicą klucz-wartość, ponieważ może zostać ona nadpisana $$foo.

Po zmianie na użycie tablicy asocjacyjnej kod będzie podlegał rozwiązaniu 1. Pośredni dostęp do właściwości obiektu (np. $foo->$property_name) Można rozwiązać za pomocą rozwiązania 2.

5. issetjest o wiele łatwiejszy do pisania niżarray_key_exists

Nie jestem pewien, czy to jest naprawdę istotne, ale tak, nazwy funkcji PHP mogą być czasem dość skomplikowane i niespójne. Najwyraźniej w prehistorycznych wersjach PHP użyto długości nazwy funkcji jako klucza skrótu, więc Rasmus celowo wymyślił nazwy funkcji htmlspecialcharstak, aby miały niezwykłą liczbę znaków ...

Ale przynajmniej nie piszemy w Javie, co? ;)

6. Niezainicjowane zmienne mają typ

Strona podręcznika na temat zmiennych podstawowych zawiera następujące stwierdzenie:

Niezainicjowane zmienne mają domyślną wartość swojego typu w zależności od kontekstu, w którym są używane

Nie jestem pewien, czy w Zend Engine istnieje jakieś pojęcie „niezainicjowanego, ale znanego typu”, czy też czyta to zbyt wiele w oświadczeniu.

Oczywiste jest, że nie ma to praktycznego wpływu na ich zachowanie, ponieważ zachowania opisane na tej stronie dla niezainicjowanych zmiennych są identyczne z zachowaniem zmiennej, której wartość jest null. Aby wybrać jeden z przykładów, jak $ai $bw tym kodzie skończy się jako liczbę całkowitą 42:

unset($a);
$a += 42;

$b = null;
$b += 42;

(Pierwszy podniesie powiadomienie o niezadeklarowanej zmiennej, próbując sprawić, że napiszesz lepszy kod, ale nie będzie miało to żadnego wpływu na to, jak naprawdę działa kod.)

99. Wykrywanie, czy funkcja się uruchomiła

(Zachowaj ten ostatni, ponieważ jest znacznie dłuższy niż inne. Może później go zmodyfikuję ...)

Rozważ następujący kod:

$test_value = 'hello';
foreach ( $list_of_things as $thing ) {
    if ( some_test($thing, $test_value) ) {
        $result = some_function($thing);
    }
}
if ( isset($result) ) {
    echo 'The test passed at least once!';
}

Jeśli some_functionmoże wrócić null, istnieje możliwość, że echonie zostanie osiągnięty, nawet jeśli zostanie some_testzwrócony true. Intencją programisty było wykrycie, kiedy $resultnigdy nie zostało ustawione, ale PHP nie pozwala na to.

Istnieją jednak inne problemy z tym podejściem, które stają się jasne, jeśli dodasz zewnętrzną pętlę:

foreach ( $list_of_tests as $test_value ) {
    // something's missing here...
    foreach ( $list_of_things as $thing ) {
        if ( some_test($thing, $test_value) ) {
            $result = some_function($thing);
        }
    }
    if ( isset($result) ) {
        echo 'The test passed at least once!';
    }
}

Ponieważ $resultnigdy nie jest jawnie inicjowany, nabierze wartości po przejściu pierwszego testu, uniemożliwiając stwierdzenie, czy kolejne testy przeszły, czy nie. To jest naprawdę bardzo częsty błąd, gdy zmienne nie są poprawnie inicjowane.

Aby to naprawić, musimy zrobić coś na linii, w której skomentowałem, że czegoś brakuje. Najbardziej oczywistym rozwiązaniem jest ustawienie $result„wartości końcowej”, która some_functionnigdy nie może powrócić; jeśli tak null, reszta kodu będzie działać poprawnie. Jeśli nie ma naturalnego kandydata na wartość końcową, ponieważ some_functionma wyjątkowo nieprzewidywalny typ zwracany (który prawdopodobnie sam w sobie jest złym znakiem), $foundmożna zamiast tego użyć np. Dodatkowej wartości logicznej .

Pierwszy eksperyment myślowy: very_nullstała

PHP teoretycznie może zapewnić specjalną stałą - a także null- do wykorzystania jako wartość końcową tutaj; prawdopodobnie zwrócenie tego z funkcji byłoby nielegalne lub byłoby do tego przymuszone null, i to samo prawdopodobnie dotyczyłoby przekazania go jako argumentu funkcji. To sprawiłoby, że ten bardzo konkretny przypadek byłby nieco prostszy, ale jak tylko zdecydowałbyś ponownie rozłożyć kod - na przykład, aby umieścić wewnętrzną pętlę w osobnej funkcji - stałby się bezużyteczny. Jeśli stała mogłaby być przekazywana między funkcjami, nie można zagwarantować, some_functionże jej nie zwróci, więc nie byłaby użyteczna jako uniwersalna wartość końcowa.

Argument wykrywania niezainicjowanych zmiennych w tym przypadku sprowadza się do argumentu dla tej specjalnej stałej: jeśli zastąpisz komentarz unset($result)i potraktujesz to inaczej $result = null, wprowadzisz „wartość” $result, której nie można przekazać, a jedynie wykryte przez określone funkcje wbudowane.

Myśl eksperyment drugi: licznik przydziału

Innym sposobem myślenia o to, o co ifpyta ostatni, jest „czy coś ma jakieś zadanie $result?” Zamiast uważać to za specjalną wartość $result, można by pomyśleć o tym jako o „metadanych” o zmiennej, trochę jak o „zabarwieniu zmiennych” przez Perla. Więc raczej niż issetmożna to nazwać has_been_assigned_to, i zamiast unset, reset_assignment_state.

Ale jeśli tak, to po co zatrzymywać się na boolean? Co jeśli chcesz wiedzieć, ile razy test przeszedł pomyślnie; możesz po prostu rozszerzyć swoje metadane na liczbę całkowitą i mieć get_assignment_counti reset_assignment_count...

Oczywiście dodanie takiej funkcji miałoby kompromis w zakresie złożoności i wydajności języka, dlatego należałoby dokładnie rozważyć jego oczekiwaną przydatność. Podobnie jak w przypadku very_nullstałej, byłby użyteczny tylko w bardzo wąskich okolicznościach i byłby podobnie odporny na ponowne faktoring.

Mam nadzieję, że oczywiste pytanie brzmi, dlaczego silnik wykonawczy PHP powinien z góry założyć, że chcesz śledzić takie rzeczy, zamiast pozostawić to jawne, używając normalnego kodu.

IMSoP
źródło
Jeśli chodzi o klasy i właściwości, niestety właściwość property_exists () nie działa, gdy właściwość jest tablicą, na przykład: Class {public $ property = array ()}. Zgłasza błąd.
Andrew
1
@Andrew Wydaje się, że działa dobrze dla mnie: 3v4l.org/TnAY5 Chcesz podać pełny przykład?
IMSoP,
tak, wydaje się, że działa dobrze, coś nie tak z moją konfiguracją. Przepraszam za fałszywy alarm :)
Andrew
20

Czasami trochę się gubię, próbując dowiedzieć się, której operacji porównania użyć w danej sytuacji. isset()dotyczy tylko niezainicjowanych lub jawnie zerowych wartości. Przekazywanie / przypisywanie wartości null to świetny sposób na zapewnienie logicznego porównania zgodnego z oczekiwaniami.

Mimo to trudno jest o tym myśleć, dlatego oto prosta macierz porównująca, w jaki sposób różne wartości będą oceniane przez różne operacje:

|           | ===null | is_null | isset | empty | if/else | ternary | count>0 |
| -----     | -----   | -----   | ----- | ----- | -----   | -----   | -----   |
| $a;       | true    | true    |       | true  |         |         |         |
| null      | true    | true    |       | true  |         |         |         |
| []        |         |         | true  | true  |         |         |         |
| 0         |         |         | true  | true  |         |         | true    |
| ""        |         |         | true  | true  |         |         | true    |
| 1         |         |         | true  |       | true    | true    | true    |
| -1        |         |         | true  |       | true    | true    | true    |
| " "       |         |         | true  |       | true    | true    | true    |
| "str"     |         |         | true  |       | true    | true    | true    |
| [0,1]     |         |         | true  |       | true    | true    | true    |
| new Class |         |         | true  |       | true    | true    | true    |

Aby dopasować się do stołu, nieco skompresowałem etykiety:

  • $a; odnosi się do zadeklarowanej, ale nieprzypisanej zmiennej
  • wszystko inne w pierwszej kolumnie odnosi się do przypisanej wartości, na przykład:
    • $a = null;
    • $a = [];
    • $a = 0;
  • kolumny odnoszą się do operacji porównania, takich jak:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false

Wszystkie wyniki są logiczne, truesą drukowane i falsepomijane.

Możesz uruchomić testy samodzielnie, sprawdź tę treść:
https://gist.github.com/mfdj/8165967

Mark Fox
źródło
Może poza zakresem tego pytania, ale możesz dodać "0"do tabeli, aby uzyskać kompletność i przejrzystość emptyoperacji
Rik Schaaf
17

Możesz użyć konstrukcji języka kompaktowego do testowania istnienia zmiennej zerowej. Zmienne, które nie istnieją, nie pojawią się w wyniku, a pojawią się wartości null.

$x = null;
$y = 'y';

$r = compact('x', 'y', 'z');
print_r($r);

// Output:
// Array ( 
//  [x] => 
//  [y] => y 
// ) 

W przypadku twojego przykładu:

if (compact('v')) {
   // True if $v exists, even when null. 
   // False on var $v; without assignment and when $v does not exist.
}

Oczywiście dla zmiennych w zakresie globalnym można również użyć array_key_exists ().

Btw osobiście unikałbym sytuacji takich jak zaraza, w której istnieje znacząca różnica między zmienną nieistniejącą a zmienną o wartości zerowej. PHP i większość innych języków po prostu tak nie uważa.

Matijs
źródło
3
PHP nie, ale nie powiedziałbym, że większość innych języków nie. Większość języków deklarujących zmienne generuje błąd, jeśli zmienna nie została zadeklarowana, ale można je ustawić na NULL. Semantycznie NULLpowinno oznaczać „brak zasobu”, ale brak zdefiniowania zmiennej jest błędem programisty.
M Miller,
1
@MMiller Pewnie, ale pisanie kodu podążającego jedną ścieżką w przypadku „braku zasobów” i inną ścieżką w przypadku „błędu programisty” jest dość nonsensowne. Jeśli chcesz wykryć niezadeklarowane zmienne podczas debugowania, użyj narzędzia analizy statycznej, tak jakbyś mógł znaleźć potencjalne błędy w dowolnym języku.
IMSoP
@MMiller, Cool, jak w ogóle o tym pomyślałeś.
Pacerier
1
@MMiller Ale to nie działa jako obalenie, ponieważ stwierdzenie w odpowiedzi wyraźnie mówi o „zmiennej nieistniejącej”, a twój przeciwny przykład dotyczy właściwości obiektu / klucza skrótu nieistniejącego . Rozróżnienie między tymi przypadkami jest nie tylko przypadkowe.
IMSoP,
1
@MMiller - to naprawdę lepszy przykład. Mimo to, po ponad 20 latach programowania w ścisłych językach, sytuacje, w których potrzebowałem rozróżnienia między, undefinedi nullsą tak rzadkie, że nie mogę tego przegapić. IMHO, głównym zastosowaniem undefinedjest „błąd programisty w języku innym niż ścisły”. W ścisłym języku, jeśli potrzebuję odrębnego stanu client did not state a value, to deklaruję wartość odpowiednią do sytuacji i testuję ją. W najgorszym przypadku trzeba dodać osobną zmienną flagi. Ale robienie tego rzadko jest lepsze niż ZAWSZE radzenie sobie z DWÓMI różnymi stanami nie-wartościowymi !!
ToolmakerSteve
15

Wyjaśniając NULL, logicznie myśląc

Myślę, że oczywistą odpowiedzią na to wszystko jest ... Nie inicjuj swoich zmiennych jako NULL, inicjuj je jako coś istotnego dla tego, czym mają się stać.

Traktuj NULL prawidłowo

NULL należy traktować jako „nieistniejącą wartość”, co oznacza NULL. Zmiennej nie można zaklasyfikować jako istniejącej w PHP, ponieważ nie powiedziano jej, jaki typ encji próbuje być. Może i nie istnieje, więc PHP po prostu mówi: „Dobrze, nie ma, bo i tak nie ma sensu, a NULL to mój sposób na powiedzenie tego”.

Kłótnia

Spierajmy się teraz. „Ale NULL jest jak powiedzenie 0, FAŁSZ lub„ ”.

Źle, 0-FAŁSZ- '' są nadal klasyfikowane jako puste wartości, ale SĄ one określone jako pewnego rodzaju wartość lub z góry określona odpowiedź na pytanie. FAŁSZ jest odpowiedzią na tak lub nie, '' jest odpowiedzią na tytuł, który ktoś przesłał, a 0 jest odpowiedzią na ilość lub czas itp. Są one ustawione jako pewnego rodzaju odpowiedź / wynik, co sprawia, że ​​są ważne jako ustawione.

NULL to po prostu żadna odpowiedź, która tak zawsze, nie mówi nam tak lub nie i nie podaje nam czasu i nie mówi nam, że przesłano pusty ciąg znaków. To podstawowa logika w rozumieniu wartości NULL.

Podsumowanie

Nie chodzi o tworzenie zwariowanych funkcji w celu obejścia problemu, ale po prostu zmienia sposób, w jaki mózg patrzy na NULL. Jeśli ma wartość NULL, załóż, że nie jest ustawiony jako cokolwiek. Jeśli wstępnie definiujesz zmienne, zdefiniuj je jako 0, FAŁSZ lub „” w zależności od zamierzonego zastosowania.

Możesz to zacytować. To jest poza moją logiczną głową :)

greatbigmassive
źródło
5
Świetna odpowiedź. Tak wiele razy widzę, jak ludzie narzekają na to, jak nienawidzą tej lub innej cechy języka. Ale oni wydają się zakładać, że „jeśli to nie robi MÓJ sposób, to jest zepsute”. Tak, są złe decyzje projektowe. Ale są też bardzo uważni programiści!
curtisdf
23
Istnieje ogromna różnica między zmienną nieustawioną a zmienną === null. Jeden nie istnieje, drugi ma wartość null. Argumenty, że null oznacza brak wartości, po prostu nie są prawdziwe. Null TO WARTOŚĆ typu null. Jest to całkowicie poprawna wartość i nie ma powodu, aby php traktował ją jako wartość nieistniejącą, co niestety robi. Byłoby OK, gdyby nieistniejące zmienne były zerowe, a każda istniejąca zmienna nie była zerowa, a przypisanie null do zmiennej rozbroiłoby ją. Są jednak WIELE sytuacji, w których funkcje zwracają wartość null jako wartość rzeczywistą. Więc jesteśmy popieprzeni, ponieważ nie ma cholernego sposobu na sprawdzenie tego.
enrey,
2
Wiem, że „nie powinniśmy” sprawdzać istnienia zmiennych w php, do diabła, nie ma nawet żadnego prawdziwego sposobu, aby to sprawdzić. Nie zamierzam pisać kodu, który na nim zależy, ponieważ nie jest to możliwe w php. To ograniczenie php. Istnieje wyraźna różnica między zmienną nieustawioną a zerową, ale php nie ma możliwości ich rozróżnienia. Jednak wiele metafunkcji zależy od niego wewnętrznie: czytanie nieistniejącego var generuje powiadomienie, isset($a['x'])powie ci fałsz, jeśli xjest null, ale pojawi się w count($a).. compactbędzie działać na wszystkich ustawionych zmiennych, w tym nullsi tak dalej.
enrey,
3
Ta odpowiedź ma jedną poważną wadę: w programowaniu OO null jest logicznym wyborem oznaczającym „brak obiektu”. Na przykład w wyjątkowych okolicznościach, gdy funkcja może zwrócić obiekt lub żaden obiekt, oczywistym wyborem jest null. Technicznie w PHP można użyć wartości false lub innej wartości uważanej za fałsz w kontekście logicznym, ale wtedy tracisz trochę czystości semantycznej. Zatem wartość null jest całkowicie rozsądną wartością do zainicjowania zmiennej, która powinna ostatecznie zatrzymać obiekt, ponieważ ma on znaczenie dla tego, czym ma być.
chazomaticus
3
Tak długo, jak PHP zgłasza błędy dla niezdefiniowanych zmiennych, ale nie dla wartości zerowej, istnieje różnica. Jeśli wartość null i undefined są tak naprawdę tą samą koncepcją, wówczas PHP powinien przyjąć domyślne niezdefiniowane / niezadeklarowane zmienne do wartości null i nigdy nie zgłaszać błędu, ale nikt tego nie chce, ponieważ jest to koszmar rozwoju. Wartość zerowa i niezdefiniowana nie mogą tak naprawdę różnić się w kontekście semantyki wartości, ale są bardzo różne, jeśli chodzi o pisanie jasnego i debugowalnego kodu.
Chris Middleton
9

Właściwości obiektu można sprawdzić pod kątem istnienia za pomocą property_exists

Przykład z testu jednostkowego:

function testPropertiesExist()
{
    $sl =& $this->system_log;
    $props = array('log_id',
                   'type',
                   'message',
                   'username',
                   'ip_address',
                   'date_added');

    foreach($props as $prop) {
        $this->assertTrue(property_exists($sl, $prop),
                           "Property <{$prop}> exists");
    }
}

źródło
4

Jako dodatek do dyskusji greatbigmassive o tym, co oznacza NULL , zastanów się, co tak naprawdę oznacza „istnienie zmiennej”.

W wielu językach musisz jawnie zadeklarować każdą zmienną przed użyciem ; może to determinować jego typ, ale co ważniejsze deklaruje jego zakres . Zmienna „istnieje” wszędzie w swoim zakresie i nigdzie poza nią - może to być cała funkcja lub pojedynczy „blok”.

W swoim zakresie zmienna przypisuje pewne znaczenie etykiecie, którą wybrałeś jako programista. Poza zakresem etykieta ta nie ma znaczenia (to, czy używasz tej samej etykiety w innym zakresie, jest w zasadzie nieistotne).

W PHP zmienne nie muszą być deklarowane - pojawiają się, gdy tylko są potrzebne. Kiedy piszesz do zmiennej po raz pierwszy, PHP przydziela wpis w pamięci dla tej zmiennej. Jeśli czytasz ze zmiennej, która obecnie nie ma pozycji, PHP uważa tę zmienną za posiadającą wartość NULL.

Jednak automatyczne detektory jakości kodu generalnie ostrzegają, jeśli użyjesz zmiennej bez jej „inicjalizacji”. Po pierwsze, pomaga to wykryć literówki, takie jak przypisywanie do, $thingIdale czytanie z $thing_id; ale po drugie, zmusza cię do rozważenia zakresu, w którym ta zmienna ma znaczenie, tak jak deklaracja.

Każdy kod, który dba o to, czy zmienna „istnieje”, jest częścią zakresu tej zmiennej - niezależnie od tego, czy została ona zainicjowana, jako programista nadałeś tej etykiecie znaczenie w tym punkcie kodu. Ponieważ go używasz, musi w pewnym sensie „istnieć”, a jeśli istnieje, musi mieć wartość domyślną; w PHP ta domyślna wartość to null.

Ze względu na sposób działania PHP możliwe jest pisanie kodu, który traktuje przestrzeń nazw istniejących zmiennych nie jako zakres etykiet, którym nadałeś znaczenie, ale jako pewnego rodzaju magazyn klucz-wartość. Można na przykład uruchomić kod jak poniżej: $var = $_GET['var_name']; $$var = $_GET['var_value'];. To, że potrafisz, nie oznacza, że ​​to dobry pomysł.

Okazuje się, że PHP ma znacznie lepszy sposób reprezentowania magazynów klucz-wartość, zwanych tablicami asocjacyjnymi. I chociaż wartości tablicy można traktować jak zmienne, można również wykonywać operacje na tablicy jako całości. Jeśli masz tablicę asocjacyjną, możesz sprawdzić, czy zawiera ona klucz, używając array_key_exists().

Możesz także używać obiektów w podobny sposób, dynamicznie ustawiając właściwości, w takim przypadku możesz używać property_exists()dokładnie w ten sam sposób. Oczywiście, jeśli zdefiniowanie klasy, można zadeklarować właściwości, które to - można nawet wybrać pomiędzy public, privatei protectedzakres.

Chociaż istnieje różnica techniczna między zmienną (w przeciwieństwie do klucza tablicy lub właściwości obiektu), która nie została zainicjowana (lub która została jawnie unset()), a tą, której wartością jest nulldowolny kod, który uważa tę różnicę za znaczącą używa zmiennych w sposób, w jaki nie powinny być używane.

IMSoP
źródło
1
Bardzo dobre punkty, choć nie do końca odpowiedź na pytanie.
chazomaticus
1
Na wyraźne pytanie „Jak mamy niezawodnie sprawdzać istnienie zmiennej w PHP?” moja odpowiedź brzmi: „nie jesteś, a oto dlaczego”. Zarówno ta odpowiedź, jak i greatbigmassive również odpowiadają na ukryte pytanie „dlaczego tak się isset()zachowuje?”.
IMSoP
„Jeśli czytasz ze zmiennej, która obecnie nie ma pozycji, PHP uważa, że ​​ta zmienna ma wartość NULL.” To nieprawda. Niezdefiniowana zmienna jest po prostu niezdefiniowana. Może próbować uzyskać do niego wartość zero, ale nie ma to znaczenia.
Hugo Zink,
@ HugoZink Nieważne na co? Jakikolwiek test wartości niezdefiniowanej zmiennej powie ci, że wartość jest null. To, czy ta wartość istnieje, zanim się na nią spojrzy, jest kwestią dla filozofów, ale jeśli chodzi o wszelkie obserwowalne zachowania, wartość jest konsekwentna null.
IMSoP
3

issetsprawdza, czy zmienna jest ustawiona, a jeśli tak, to czy jej wartość nie jest równa NULL. Ta ostatnia część (moim zdaniem) nie wchodzi w zakres tej funkcji. Nie ma przyzwoitego obejścia, aby ustalić, czy zmienna ma wartość NULL ponieważ nie jest ustawiona lub ponieważ jest jawnie ustawiona na NULL .

Oto jedno z możliwych rozwiązań:

$e1 = error_get_last();
$isNULL = is_null(@$x);
$e2 = error_get_last();
$isNOTSET = $e1 != $e2;
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0

Innym obejściem jest sondowanie danych wyjściowych get_defined_vars():

$vars = get_defined_vars();
$isNOTSET = !array_key_exists("x", $vars);
$isNULL = $isNOTSET ? true : is_null($x);
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0
Salman A.
źródło
2

Nie zgadzam się z twoim rozumowaniem na temat wartości NULL , a mówienie, że musisz zmienić sposób myślenia o wartości NULL, jest po prostu dziwne.

Myślę, że isset () nie został poprawnie zaprojektowany, isset () powinien powiedzieć ci, czy zmienna została ustawiona i nie powinna zajmować się faktyczną wartością zmiennej.

Co jeśli sprawdzasz wartości zwrócone z bazy danych, a jedna z kolumn ma wartość NULL, nadal chcesz wiedzieć, czy istnieje, nawet jeśli wartość wynosi NULL ... tutaj nie ufaj isset () tutaj.

również

$a = array ('test' => 1, 'hello' => NULL);

var_dump(isset($a['test']));   // TRUE
var_dump(isset($a['foo']));    // FALSE
var_dump(isset($a['hello']));  // FALSE

isset () powinien być zaprojektowany tak, aby działał w następujący sposób:

if(isset($var) && $var===NULL){....

w ten sposób pozostawiamy programistom sprawdzenie typów, a nie pozostawienie go do isset (), aby założyć, że nie ma go tam, ponieważ wartość wynosi NULL - to po prostu głupi projekt

Christof Coetzee
źródło
Twój przykład nie sprawdza istnienia zmiennej, ale klucza tablicy. Istnieje na to rozwiązanie w postaci array_key_exists. Nigdy nie powinieneś znajdować się w sytuacji, w której w czasie wykonywania nie wiesz, czy istnieje rzeczywista zmienna.
IMSoP
@chazomaticus Cóż, nigdy nie powinieneś być w sytuacji, gdy register_globals jest włączony, więc trzymam się tego stwierdzenia.
IMSoP,
Och, zgadzam się. Jednak nie wszyscy mogą kontrolować, gdzie jest wdrażany ich kod. Przydatne jest posiadanie informacji na temat każdej sytuacji, niezależnie od tego, jak rzeczy powinny być, czy nie.
chazomaticus
@chazomaticus Jeśli masz problem register_globals, twoja odpowiedź nie jest zmianą na isset(). Podręcznik PHP wspomina „naprawdę dobrą praktyką programistyczną jest najpierw inicjowanie zmiennych”, które rozwiązuje się register_globalsw czasie projektowania, a nie w czasie wykonywania. Dostępna jest również pozycja FAQ, która zawiera unregister_globals()funkcję radzenia sobie z nią w czasie wykonywania.
IMSoP
2

Dodam do tego szybkie dwa centy. Jednym z powodów, dla których ten problem jest mylący, jest to, że ten scenariusz wydaje ten sam wynik, gdy raportowanie błędów nie jest pełne:

$a = null;
var_dump($a); // NULL
var_dump($b); // NULL

Na podstawie tego wyniku można założyć, że różnica między $a = nulldefinicją a jej brakiem $bjest niczym.

Zgłaszanie błędu korby:

NULL

Notice: Undefined variable: b in xxx on line n
NULL

Uwaga: zgłosił błąd niezdefiniowanej zmiennej, ale wartość wyjściowa var_dumpnadal jest NULL.

PHP oczywiście ma wewnętrzną zdolność do rozróżniania zmiennej pustej od zmiennej niezdefiniowanej. Wydaje mi się, że powinna istnieć wbudowana funkcja sprawdzania tego.

Myślę, że zaakceptowana odpowiedź jest w większości dobra, ale gdybym miał ją wdrożyć, napisałbym dla niej opakowanie. Jak wcześniej wspomniano w tej odpowiedzi , muszę zgodzić się, że tak naprawdę nie spotkałem się z sytuacją, w której był to problem. Wydaje mi się, że prawie zawsze kończy się na scenariuszu, w którym moje zmienne są albo ustawione i zdefiniowane, albo nie są (niezdefiniowane, nieustawione, zerowe, puste itd.). Nie mówiąc już o tym, że taka sytuacja nie wystąpi w przyszłości, ale ponieważ wydaje się to być dość wyjątkowym problemem, nie dziwię się, że deweloperzy PHP nie zadali sobie trudu, aby to zrobić.

Robbie Averill
źródło
Ostrzeżenie o niezdefiniowanych zmiennych jest wskazówką dla programisty, że zrobili coś złego w kodzie. Poza debugowaniem (dla których istnieją narzędzia spoza języka) program nigdy nie powinien wykrywać takiego stanu, ponieważ programista powinien zawsze wiedzieć, jakie zmienne deklaruje.
IMSoP
1

Jeśli uruchomię następujące:

echo '<?php echo $foo; ?>' | php

Dostaję błąd:

PHP Notice:  Undefined variable: foo in /home/altern8/- on line 1

Jeśli uruchomię następujące:

echo '<?php if ( isset($foo) ) { echo $foo; } ?>' | php

Nie dostaję błędu.

Jeśli mam zmienną, którą należy ustawić, zwykle robię coś takiego.

$foo = isset($foo) ? $foo : null;

lub

if ( ! isset($foo) ) $foo = null;

W ten sposób, w dalszej części skryptu, mogę bezpiecznie używać $ foo i wiem, że „jest ustawiony” i że domyślnie ma wartość null. Później mogę, if ( is_null($foo) ) { /* ... */ }jeśli muszę i wiem na pewno, że zmienna istnieje, nawet jeśli jest pusta.

Pełna dokumentacja isset zawiera więcej niż tylko to, co początkowo zostało wklejone. Tak, zwraca false dla zmiennej, która była wcześniej ustawiona, ale teraz ma wartość NULL, ale zwraca również false, jeśli zmienna nie została jeszcze ustawiona (kiedykolwiek) i dla każdej zmiennej, która została oznaczona jako nieustawiona. Zauważa również, że bajt NULL („\ 0”) nie jest uważany za pusty i zwróci wartość true.

Określ, czy zmienna jest ustawiona.

Jeśli zmienna została rozbrojona za pomocą unset (), nie będzie już ustawiana. isset () zwróci FALSE, jeśli testowana jest zmienna ustawiona na NULL. Zauważ też, że bajt NULL („\ 0”) nie jest równoważny stałej PHP NULL.

Beau Simensen
źródło
Usunął dokumenty z tego linku. Przeczytaj pierwsze zdanie, drugi akapit sekcji opisu pod podanym linkiem. Dokładnie to, co cytował powyżej.
Zoredache
Nie jest to zła praktyka w przypadku prostych skryptów, ale w złożonych projektach (np. Dużych OO) staje się niemożliwa. Ponadto, jak powiedziałem powyżej, is_null () zwraca PRAWDA dla zmiennych, które nie są ustawione, więc naprawdę nie ma powodu, aby robić to, co mówisz, z wyjątkiem unikania ostrzeżenia PHP.
chazomaticus
1
Dlaczego w przypadku dobrze zaprojektowanych „dużych OO” w ogóle miałby to stanowić problem? Dlaczego miałbyś mieć $ foo w treści metody, która mogła nie zostać ustawiona przed pierwszym użyciem?
Beau Simensen
1

Spróbuj użyć

unset($v)

Wydaje się, że zmienna nie jest ustawiona tylko wtedy, gdy jest specyficznie rozbrojona ($ v). Wygląda na to, że twoje znaczenie „istnienia” różni się od definicji PHP. NULL z pewnością istnieje, jest NULL.

Joe Phillips
źródło
Nie jestem pewny co masz na myśli. Jeśli masz tablicę z jednym elementem „a”, nie musisz wyłączać () elementu „b”, aby element „b” nie istniał w PHP, po prostu nie istnieje. To samo dotyczy np. Zmiennych globalnych, które można traktować jako elementy tablicy $ GLOBALS.
chazomaticus
1
Ale zgadzam się, że w rzeczywistości istnieje zmienna o wartości NULL.
chazomaticus
0

Muszę powiedzieć przez wszystkie lata programowania PHP, że nigdy nie spotkałem się z problemem isset()zwracania wartości false w zmiennej null. OTOH, napotkałem problemy z isset()niepowodzeniem przy wpisie pustej tablicy - ale array_key_exists()w takim przypadku działa poprawnie.

Dla porównania, Icon wyraźnie definiuje nieużywaną zmienną jako zwracaną, &nullwięc używasz testu is-null w Icon, aby również sprawdzić, czy nie jest ustawiona zmienna. To ułatwia rzeczy. Z drugiej strony Visual BASIC ma wiele stanów dla zmiennej, która nie ma wartości (Null, Empty, Nothing, ...), i często trzeba sprawdzać więcej niż jeden z nich. Jest to znane jako źródło błędów.

staticsan
źródło
0

Zgodnie z instrukcją PHP dla funkcji empty (): „Ustal, czy zmienna jest uważana za pustą. Zmienna jest uważana za pustą, JEŚLI NIE ISTNIEJE lub jeśli jej wartość jest równa FAŁSZ. Pusta () nie generuje ostrzeżenia, jeśli właściwość zmienna nie istnieje. ” (Podkreślam.) Oznacza to, że funkcja empty () powinna kwalifikować się jako „najlepszy sposób na sprawdzenie istnienia zmiennej w PHP”, zgodnie z tytułem Pytanie.

Nie jest to jednak wystarczające, ponieważ funkcję empty () można oszukać za pomocą zmiennej, która istnieje i jest ustawiona na NULL.

Przerywam moją wcześniejszą odpowiedź, aby przedstawić coś lepszego, ponieważ jest to mniej kłopotliwe niż moja pierwotna odpowiedź (która następuje po tej przerwie, dla porównania).

  function undef($dnc) //do not care what we receive
  { $inf=ob_get_contents();             //get the content of the buffer
    ob_end_clean();                     //stop buffering outputs, and empty the buffer
    if($inf>"")                         //if test associated with the call to this function had an output
    { if(false!==strpos($inf, "Undef"); //if the word "Undefined" was part of the output
        return true;                    //tested variable is undefined
    }
    return false;                       //tested variable is not undefined
  }

Dwie proste linie kodu mogą wykorzystać powyższą funkcję do ujawnienia, czy zmienna jest niezdefiniowana:

  ob_start();                           //pass all output messages (including errors) to a buffer
  if(undef($testvar===null))            //in this case the variable being tested is $testvar

Możesz podążać za tymi dwoma wierszami we właściwy sposób, na przykład w tym przykładzie:

    echo("variable is undefined");
  else
    echo("variable exists, holding some value");

Chciałem umieścić wywołanie funkcji ob_start () i ($ testvar === null) wewnątrz funkcji i po prostu przekazać zmienną do funkcji, ale to nie działa. Nawet jeśli spróbujesz użyć funkcji „przekaż referencję” zmiennej do funkcji, zmienna BECOMES została zdefiniowana, a wtedy funkcja nigdy nie wykryje, że poprzednio była niezdefiniowana. Przedstawiono tu kompromis między tym, co chciałem zrobić, a tym, co faktycznie działa.

Z powyższego wynika, że ​​istnieje inny sposób na zawsze uniknięcie komunikatu o błędzie „Niezdefiniowana zmienna”. (Założenie jest takie, że zapobieganie takiemu komunikatowi jest powodem, dla którego chcesz przetestować, czy zmienna jest niezdefiniowana).

   function inst(&$v) { return; }  //receive any variable passed by reference; instantiates the undefined

Po prostu wywołaj tę funkcję, zanim zrobisz coś z $ testvar:

   inst($testvar);                //The function doesn't affect any value of any already-existing variable

Oczywiście wartość nowo utworzonej instancji jest ustawiona na null!

(Przerwanie kończy się)

Po kilku studiach i eksperymentach, oto coś, co zadziała:

 function myHndlr($en, $es, $ef, $el)
 { global $er;
   $er = (substr($es, 0, 18) == "Undefined variable");
   return;
 }

 $er = false;
 if(empty($testvar))
 { set_error_handler("myHndlr");
   ($testvar === null);
   restore_error_handler();
 }
 if($er)  // will be 1 (true) if the tested variable was not defined.
 { ; //do whatever you think is appropriate to the undefined variable
 }

Wyjaśnienie: Zmienna $ er jest inicjowana na wartość domyślną „brak błędu”. Zdefiniowano „funkcję modułu obsługi”. Jeśli $ testvar (zmienna, którą chcemy wiedzieć, czy jest niezdefiniowana) przejdzie wstępny test funkcji pustej (), wówczas przeprowadzimy dokładniejszy test. Wywołujemy funkcję set_error_handler (), aby użyć wcześniej zdefiniowanej funkcji modułu obsługi. Następnie wykonujemy proste porównanie tożsamości z udziałem $ testvar, KTÓRE JEŚLI NIEODDEFINOWANE SPOWODUJE BŁĄD. Funkcja modułu obsługi przechwytuje błąd i konkretnie sprawdza, czy przyczyną błędu jest fakt, że zmienna jest niezdefiniowana. Wynik jest umieszczany w zmiennej $ er informacji o błędach, którą możemy później przetestować, aby zrobić wszystko, co chcemy, w wyniku pewności, czy $ testvar został zdefiniowany. Ponieważ potrzebujemy tylko funkcji obsługi do tego ograniczonego celu, przywracamy pierwotną funkcję obsługi błędów. Funkcję „myHndlr” należy zadeklarować tylko raz; drugi kod można skopiować do odpowiednich miejsc, dla $ testvar lub dowolnej innej zmiennej, którą chcemy przetestować w ten sposób.

vernonner3voltazim
źródło
1
Jeśli celem jest uniknięcie ostrzeżenia, że ​​zmienne nie zostały zadeklarowane, rozwiązaniem jest poprawienie kodu w celu ich poprawnego zadeklarowania. Twoja instfunkcja jest w zasadzie podobna do @operatora tłumienia błędów: „Wiem, że robię tu coś złego, ale chcę tylko, aby ten komunikat zniknął, nie zmieniając w żaden sposób działania mojego kodu”.
IMSoP
Z drugiej strony metody wykrywania są genialne, ale nadal jestem głęboko przekonany, że nigdy nie powinieneś używać ich do niczego innego, jak tylko do echa bardzo ostrzeżeń, które łapią. (Prawdopodobnie powinieneś wyjaśnić, że twoja wersja buforowania danych wyjściowych wymaga
raportowania błędów
0

Myślę, że jedynym rozwiązaniem jest pełna do zgłaszania zawiadomień o

error_reporting(E_ALL); // Enables E_NOTICE

Ale będziesz musiał naprawić wszystkie powiadomienia generowane między innymi przez niezdefiniowane zmienne, stałe, klucze tablicy, właściwości klasy. Gdy to zrobisz, nie będziesz musiał martwić się różnicą między zmiennymi zerowymi i niezadeklarowanymi, a dwuznaczność znika.

Włączenie raportowania powiadomień może nie być dobrą alternatywą we wszystkich sytuacjach, ale istnieją dobre powody, aby je włączyć:

Dlaczego powinienem naprawić błędy E_NOTICE?

W moim przypadku ponad rok pracował w proyectie bez niego, ale był używany, aby zachować ostrożność przy deklarowaniu zmiennych, więc przejście było szybkie.

mikl
źródło
0

Jedynym sposobem na sprawdzenie, czy zmienna jest zdefiniowana w bieżącym zakresie ( $GLOBALSnie jest wiarygodna), jest array_key_exists( 'var_name', get_defined_vars() ).

Kostas Podias
źródło
1
Myślę, że tak mówili wcześniej inni ludzie, czy się mylę?
Stephan Vierkant
-1

Wolę używać opcji „pusty” jako najlepszej metody sprawdzania istnienia zmiennej, że a) istnieje, a b) nie jest pusta.

if (!empty($variable)) do_something();
Hal
źródło
2
empty()nie sprawdza, czy zmienna ma wartość null, sprawdza czy to fałszywy-y, na przykład nie jedną z ""(pusty ciąg znaków), 0(0 jako liczbę całkowitą) 0.0(0 jako float), "0"(0 jako ciąg znaków) NULL, FALSE, array()(pusta tablica) i $var;(zmienna zadeklarowana, ale bez wartości). Załóżmy, że masz wymagane pole radiowe w formie z dwoma wejściami z wartościami 0i 1. Jeśli użyjesz empty()do sprawdzania poprawności, a użytkownik wybierze to 0, nieumyślnie popełnisz błąd „wymagane pole nie może być puste”. Zobacz instrukcję php.net/manual/en/function.empty.php
Halil Özgür