Řekněme, že mám takovou datovou strukturu:
array(3) { ["id"]=> int(1) ["name"]=> string(3) "foo" ["message"]=> array(1) { ["action"]=> string(3) "PUT" } }
Kde „zpráva“ i „akce“ jsou volitelné. Chcete-li zkontrolovat, zda se jedná o můj první pokus, bylo by napsat něco takového:
if (array_key_exists("message", $array) && array_key_exists("action", $array["message"])){ }
Existuje čistší implementace?
Komentáře
- Viz také: stackoverflow.com/questions/2948948/… Můžete napsat obslužnou funkci array_key_exists, která funguje rekurzivně.
Odpověď
Ne, toto je to jen způsob, jak to udělat.
I když nejsem omezen na určitý skriptovací jazyk, nemůžu myslet na čistší řešení?
Odpověď
Můžete to udělat jen vy!
if (isset($array["message"]["action"])) { /*...*/ }
Důkaz:
<?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
Žádné položky protokolu.
Nezapomeňte, že pokud vaše hodnota je null
, pak isset také vrátí hodnotu false. Pravděpodobně byste neměli vytvářet hodnoty pomocí null
.
Komentáře
- V této odpovědi také chybí
)
a může způsobit generování položky protokolu kvůli nekontrolováníisset($array['message'])
než jej dereferencovat. - @Brythan ne, nezpůsobí to záznam protokolu. Ale ano, chybí
)
. - Omlouvám se, chtěl jsem poukázat na to, že ' musíte hlášení chyb. Absolutně způsobí položku protokolu, pokud pro ni máte nastaveno hlášení chyb. ' jsem to dříve spamoval svými protokoly. Toto bylo výchozí protokolování v jednom bodě. Možná to teď není výchozí nastavení (nebo váš hostitel mohl vytočit hlášení chyb), ale jsem si naprosto jist, že tato situace může v určitých konfiguracích vygenerovat položku protokolu.
- Ne, opravdu to ' t Testoval jsem to se zapnutým hlášením všech chyb!
Odpověď
Není jasnější, ale pravděpodobně nejrychlejší řešení:
if ((isset($array["message"]["action"]) || (array_key_exists("message", $array) && array_key_exists("action", $array["message"]))) { /* ... */ }
Je nutná druhá kontrola, protože některé hodnoty byly vyhodnoceny pomocí isset()
bude výsledkem false, přestože index neexistuje.
Odpověď
Používám to v mém projektu, ale já “ m pomocí null
jako ztlumeného stavu. (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; }
Je to funkce, která vyhledá path
ve stromu.
echo option_select([A=>[B=>[C=>"hello world"]]], "NO?", "A", "B", "C");
Jak vidíte. Opakuji hodnoty nad polem: path
. Na začátku nastavuji kurzor jako odkaz na pole, ve kterém musím hledat. Pokaždé, když najdu klávesu new
, nastavím odkaz kurzoru na aktuální klíč hledám. Pokud máte xdebug
a dobré grafické uživatelské rozhraní, můžete jej přepsat na požadovaný algoritmus. Je to isset($cursor[$key])
musíte se změnit. Nebo jej vložte jako funkci: f($cursor, $key, $default) => (bool)
Komentáře
- Poskytli jste alternativní řešení, ale kód nebyl zkontrolován. Přidejte prosím vysvětlení, proč by to bylo pro OP lepší řešení než to, co již mají.
- Protože to není ' silně napsaný SirPython. Tímto způsobem jej mohu otestovat pomocí jednotkových testů, aniž bych prováděl jednotkový test pro každý ' hardcoded-string '. Takže to musí být s testovatelností a rychlostí, kterou dokážu vytvořit pracovní kód.
Odpověď
Hledal jsem podobný řešení sám a přišel s tím. Funguje tak, aby zjistil, zda je klíč nastaven vůbec – a vrátí PRAVDA, i když hodnota klíče „action“ je NULL.
if (isset($array["message"]) && array_key_exists("action",$array["message"])) { /* ... */ }
If $array["message"]
nemá žádné klíče, isset
vrátí FALSE a zastaví příkaz IF. Pokud $array["message"]
má nějaké klíče – i ty s hodnotami NULL – isset
vrátí TRUE, což vám umožní bezpečně zkontrolovat, zda "action"
klíč pole existuje v $array["message"]
.