O istnieniu operatora
@ najlepiej zapomnieć w ogóle. Nie dość, że jest on powolny, to jeszcze ukrywa wszystkie błędy, jakie są możliwe w PHP. To jest jedyna prawdziwie poprawna forma.
if(isset($_COOKIE['ciastko']) && in_array($_COOKIE['ciastko'], $wartosci)) {
/// ...
}
Pierwsze niekoniecznie jest bardziej przejrzyste i na dodatek może zadziałać niezgodnie z Twoimi oczekiwaniami. Sprawdź sobie działanie poniższego kodu z niezainicjowanym
$_GET['foo']:
<?php
$wartosci = array('bar', null);
{
echo 'Warunek 1 spelniony.<br/>'; }
{
echo 'Warunek 2 spelniony.<br/>'; }
Hehe, nic nie ustawiamy, a nam warunek 1 uznaje za spełniony. PHP w przypadku niezainicjowanych zmiennych generuje dla nich specjalną wartość
null. Przypuśćmy, że ten kod jest jakimś zabezpieczeniem serwisu i wskutek literówki w tablicy dozwolonych wartości znalazł się
null, a na jej podstawie przyznawany jest dostęp do jakiejś operacji. Puszasz serwis do Internetu i po pewnym czasie ktoś odkrywa, że jak skasuje sobie zmienną z adresu, to zabezpieczenie opada i zaczyna to bezlitośnie wykorzystywać, a ty płacesz, bo ktoś się włamuje. Ja jestem mądry i mam wbite do głowy, że istnienie zmiennych sprawdza się przez
isset(). Ponadto dzięki eliminowaniu błędów E_NOTICE na etapie tworzenia wiem od razu, że zrobiłem literówkę i problemu nie mam, a gdyby nawet coś pozostało niezauważone, to na pewno nikt mi nie będzie robić kuku przez zwykłe skasowanie zmiennej w adresie bądź ciastka. Zrozum, że przyrównywanie wartości do nulla to nie jest żadna kontrola, szczególnie jak nie ma się do końca pojęcia, jak coś działa. Każdy szanujący się programista po prostu sprawdza warunki brzegowe i inicjuje zmienne przed użyciem, a nie szuka dróg na skróty, bo mu się nie chce paru dodatkowych linijek wklepać, a później się dziwi, że mu się strona sypie.
W Javie to by się taki kod nawet nie skompilował, albo rzucał Ci wyjątkiem, bezlitośnie przypominając, że olewanie kontroli danych mści się później okrutnie.