Powiedzmy, że mam taką strukturę danych:
array(3) { ["id"]=> int(1) ["name"]=> string(3) "foo" ["message"]=> array(1) { ["action"]=> string(3) "PUT" } }
Gdzie „wiadomość” i „akcja” są opcjonalne. Aby sprawdzić, czy są one ponownie obecne, pierwszą próbą byłoby napisanie czegoś takiego:
if (array_key_exists("message", $array) && array_key_exists("action", $array["message"])){ }
Czy istnieje czystsza implementacja?
Komentarze
- Zobacz też: stackoverflow.com/questions/2948948/… Możesz napisać funkcję narzędzia array_key_exists, która działa rekurencyjnie.
Odpowiedź
Nie, to to tylko sposób na zrobienie tego.
Nawet jeśli nie jestem ograniczony do określonego języka skryptowego, nie mogę wymyślić czystszego rozwiązania?
Odpowiedź
Możesz to po prostu zrobić!
if (isset($array["message"]["action"])) { /*...*/ }
Dowód:
<?php error_reporting(E_ALL); ini_set("error_reporting", E_ALL); ini_set("display_errors", 1); $array = [ "id" => 1, "name" => "foo", "message" => [ "action" => "PUT", ], ]; var_dump(isset($array["message"]["action"])); // true $array = [ "id" => 1, "name" => "foo" ]; var_dump(isset($array["message"]["action"])); // false
Brak wpisów w dzienniku.
Pamiętaj, że jeśli Twoja wartość to null
, to isset również zwróci false. Prawdopodobnie nie powinieneś tworzyć wartości z null
.
Komentarze
- W tej odpowiedzi brakuje również
)
i może to spowodować wygenerowanie wpisu dziennika z powodu braku zaznaczeniaisset($array['message'])
przed wyłuskiwaniem go. - @Brythan no nie powoduje wpisu do dziennika. Ale tak, brakuje
)
. - Przykro mi, chciałem zaznaczyć, że ' musisz podkręć raportowanie błędów. To bezwzględnie powoduje wpis w dzienniku, jeśli masz ustawione raportowanie błędów. ' już wcześniej spamowało moje logi. W pewnym momencie było to domyślne logowanie. To może nie być teraz domyślne (lub twój host mógł wyłączyć raportowanie błędów), ale jestem absolutnie pewien, że ta sytuacja może wygenerować wpis dziennika w pewnych konfiguracjach.
- Nie, tak naprawdę nie ' t Przetestowałem go z włączonym raportowaniem błędów!
Odpowiedź
Nie jaśniejsze, ale prawdopodobnie najszybsze rozwiązanie:
if ((isset($array["message"]["action"]) || (array_key_exists("message", $array) && array_key_exists("action", $array["message"]))) { /* ... */ }
Drugie sprawdzenie jest potrzebne, ponieważ niektóre wartości zostały obliczone za pomocą isset()
da wynik fałsz, mimo że indeks istnieje.
Odpowiedź
Używam tego w moim projekcie, ale ja ” m używam null
jako wyciszonego stanu. (php 5.6)
<?php function &option_select($options, $default, ...$path) { if(!isset($path[0])) { return $options; } $cursor = &$options; foreach($path as $key) { if(isset($cursor[$key])) { $cursor = &$cursor[$key]; } else { return $default; } } return $cursor; }
Jest to funkcja, która wyszuka path
w drzewie.
echo option_select([A=>[B=>[C=>"hello world"]]], "NO?", "A", "B", "C");
Jak widać. Przeglądam wartości w tablicy: path
. Na początku ustawiam kursor jako odniesienie do tablicy, w której muszę szukać. Za każdym razem, gdy znajduję klawisz new
, ustawiam odniesienie kursora do obecny klucz I, którego szukam. Jeśli masz xdebug
i dobry interfejs graficzny, możesz przepisać go na żądany algorytm. To isset($cursor[$key])
musisz się zmienić. Lub wstrzyknij go jako funkcję: f($cursor, $key, $default) => (bool)
Komentarze
- Podałeś alternatywne rozwiązanie, ale masz nie sprawdziłem kodu. Proszę dodać wyjaśnienie, dlaczego byłoby to lepsze rozwiązanie dla OP, zamiast tego, co już mają.
- Ponieważ nie jest ' t silnie wpisany SirPython. W ten sposób mogę przetestować go za pomocą testów jednostkowych, bez wykonywania testu jednostkowego dla każdego ' ciągu znaków zakodowanych na stałe '. Jest to związane z testowalnością i szybkością tworzenia działającego kodu.
Odpowiedź
Szukałem podobnego rozwiązanie samodzielnie i wymyśliłem to. Działa, aby określić, czy klucz jest w ogóle ustawiony – i zwróci wartość TRUE, nawet jeśli wartość klucza „action” wynosi NULL.
if (isset($array["message"]) && array_key_exists("action",$array["message"])) { /* ... */ }
Jeśli $array["message"]
nie ma kluczy, isset
zwróci FALSE zatrzymując instrukcję IF. Jeśli $array["message"]
ma jakieś klucze – nawet te o wartościach NULL – isset
zwróci wartość TRUE, umożliwiając bezpieczne sprawdzenie, czy "action"
klucz tablicy istnieje w $array["message"]
.