2010-12-14 8 views
7

Czy można użyć funkcji @ przy wyodrębnianiu prawdopodobnie brakującej wartości z tablicy PHP? Przykład:

$value = @$array['possibly_missing_key']; 

zamierzone zachowanie:

if (isset($array['possibly_missing_key'])) { 
    $value = $array['possibly_missing_key']; 
} else { 
    $value = null; 
} 

Chcę wiedzieć, przed nałożeniem wzorca użytkowania.

+5

Czy jestem jedyną osobą używającą [array_key_exists] (http://ca.php.net/manual/en/function.array-key-exists.php) zamiast isset dla tego rodzaju rzeczy? – AlexV

+1

* (sidenote) * 'isset' nie wykrywa * prawdopodobnie brakującego klucza *. Użyj 'array_key_exists' do tego. Wypróbuj '$ arr = array ('notMissing' => NULL);' with 'isset' – Gordon

+1

@AlexV @Gordon: Nie sądzę, aby miało to znaczenie, ponieważ domyślna wartość to NULL mimo wszystko: P – BoltClock

Odpowiedz

8

Operator @ pomija komunikaty o błędach, a użycie go potencjalnie ustawia kod dla innych błędów i nieoczekiwanych zachowań, które mogą być trudne do wyśledzenia. Jest to z pewnością antipattern.

Dlatego bardzo bym wolał ten drugi kawałek. To sprawia, że ​​znacznie wyraźniejsze

  • , że nie może być obecny w tablicy, a
  • , jaka jest wartość domyślna to jeśli nie jest obecny

Aby uczynić go bardziej zwięzły można używać trójskładnikowej operator warunkowy ?:, jak widać w Mark Baker's answer. Nieco mniej kodu i więcej symboli, ale znaczenie jest dobrze rozpoznane.

+1

Rozumiem. Bezpieczne używanie może wprowadzić innych deweloperów w używanie ich w niewłaściwych miejscach. –

4

Albo

$value = (isset($array['possibly_missing_key'])) ? $array['possibly_missing_key']: null; 
+1

+1 Jeśli używasz PHP> = 5.3 możesz użyć nowej krótszej formy: 'isset ($ array ['possible_missing_key'])?: Null;' – webbiedave

+4

@webbiedave: Nie, to by zwróciło wynik 'isset (.. .) ', a nie rzeczywista wartość tablicy. – BoltClock

+0

@webbiedave: czy ta krótka wersja będzie działać w tym przypadku? Czy nie zwróci wartości 'isset()' (tj. Prawda czy fałsz) zamiast samej zmiennej? – Spudley

1

Ignorując ostrzeżenia jest zdecydowanie antywzorzec projektowy; więc tak, to anty-wzór (i mogę zagwarantować, że jeśli nauczysz się tłumić ostrzeżenia, jeden z nich wróci i ugryzie cię w tylnym, jeśli nie gorszym).

Ponadto, podczas gdy druga wersja jest bardziej szczegółowa, nadaje niezainicjowanej zmiennej znany stan (lub może być używana do obsługi problemu, jeśli zmienna ma być wypełniona).

1

Trzecia opcja:

$value = (isset($array['key']) ? $array['key'] : null); 

wiem, że to nie bezpośrednio odpowiedzieć na pytanie; Powiedziałbym to jako komentarz, ale naprawdę musiał być sformatowany.

Pomysł polega na tym, że jeśli próbujesz skrócić kod za pomocą jednolinijki zamiast bloku if-else, możesz nadal utworzyć zwięzłą linijkę za pomocą potrójnego operatora, dając ci to, co najlepsze z obu światów.

+0

To naprawdę nie trzecia opcja, to inne formatowanie opcji 2 (ponieważ jest funkcjonalnie identyczne). Czy powiedziałbyś, że 'if (x) {something}' i 'if (! X) {} else {something}' to dwa różne rozwiązania, ponieważ nie są napisane w ten sam sposób? – Piskvor

+0

@ Piskvor - hm, to trochę wybredne. Jest to inna składnia, więc powiedziałbym, że tak, to trzecia opcja, nawet jeśli jest skutecznie identyczna z oryginalnym kodem. Ale moim celem było stworzenie jednego liniowego sposobu na zrobienie tego bez użycia '@ ', ponieważ wydawało się, że jego pytanie było wędkarskie. – Spudley

+0

Cóż, jestem w pewien sposób związany z tym problemem. Składnia jest inna, ale robi to samo. Masz rację, że jest mniej gadatliwy, przy jednoczesnym zachowaniu funkcjonalności. (Wydaje mi się, że mówi więcej o moich żarłocznych impulsach niż o danym pytaniu;)) – Piskvor

1

Drugi blok kodu (lub alternatywa Marka Bakera, która będzie działać dokładnie tak samo) jest lepsza. Nie jestem do końca pewien na temat PHP, ale w wielu innych językach programowania, po prostu zignorowanie zmiennej prawie na pewno spowodowałoby błąd. Przynajmniej z drugim blokiem inicjujesz zmienną do pewnej wartości lub lokalizacji pamięci.

Usterka błędów powinna być częściej używana, jeśli oczekuje się, że funkcja wyśle ​​oczekiwany błąd w produkcie końcowym (jednak przez większość czasu tak nie jest).

Powodzenia!
Dennis M.

6

W rzeczywistości zmiana isset jest anty-wzorem.Jeśli po prostu użyjesz isset($var)?$var:NULL z zamiarem stłumienia "błędu", to nic nie osiągniesz, używając właściwej składni do tłumienia błędów. Ma taki sam wynik, ale jest mniej czytelny.

Ludzie się o to spierają, ponieważ postrzegana jest "czystość", a używanie isset to mikrooptymalizacja. Unikanie @ i używanie isset jako wymiany soli syntaktycznej to tylko programowanie kultowe ładunku.

+0

"kultowe programowanie ładunków" lol – BoltClock

+0

Dziękuję za wzmiankę o sprzecznym spojrzeniu. –

+0

@IvoDanihelka: Właściwie chcę się wycofać i dodać dużą ** to wszystko zależy **. Nie ma jednego wzorca pasującego do wszystkich przypadków użycia. Bądź elastyczny, nie religijny, jeśli chodzi o isset/@, skorzystaj z najlepszego narzędzia do pracy. – mario

Powiązane problemy