Kontrola existujícího klíče ve vícerozměrném poli

Ř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

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"].

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *