Controleren op bestaande sleutel in multidimensionale array

Stel dat ik een datastructuur als deze heb:

array(3) { ["id"]=> int(1) ["name"]=> string(3) "foo" ["message"]=> array(1) { ["action"]=> string(3) "PUT" } } 

Waar “bericht” en “actie” beide optioneel zijn. Om te controleren of ze aanwezig zijn, zou mijn eerste poging zijn om zoiets als dit te schrijven:

if (array_key_exists("message", $array) && array_key_exists("action", $array["message"])){ } 

Is er een schonere implementatie?

Opmerkingen

Answer

Nee, dit is gewoon de manier om het te doen.

Zelfs als ik “niet beperkt ben tot een bepaalde scripttaal, kan ik” geen schonere oplossing bedenken?

Antwoord

Je kunt dit gewoon doen!

if (isset($array["message"]["action"])) { /*...*/ } 

Bewijs:

<?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 

Geen logboekvermeldingen.

Houd er rekening mee dat als je waarde is null, dan zal isset ook false retourneren. Je zou waarschijnlijk “geen waarden moeten maken met null.

Opmerkingen

  • Dit antwoord mist ook een ) en kan ertoe leiden dat een logboekinvoer wordt gegenereerd doordat isset($array['message']) voordat er een dereferentie naar wordt gehaald.
  • @Brythan nee het veroorzaakt geen logboekinvoer. Maar ja, er ontbreekt een ).
  • Sorry, ik wilde erop wijzen dat je ' zou moeten zet uw foutrapportage aan. Het veroorzaakt absoluut een logboekinvoer als u uw foutrapportage ervoor hebt ingesteld. Ik ' heb het eerder mijn logboeken laten spammen. Dit was op een gegeven moment de standaardregistratie. Het is nu misschien niet de standaard (of je host heeft mogelijk foutrapportage gebeld), maar ik ben er absoluut zeker van dat die situatie onder bepaalde configuraties een logboekinvoer kan genereren.
  • Nee, dat doet het echt niet ' t Ik heb het getest met alle foutrapportage ingeschakeld!

Antwoord

Niet duidelijker maar waarschijnlijk de snelste oplossing:

if ((isset($array["message"]["action"]) || (array_key_exists("message", $array) && array_key_exists("action", $array["message"]))) { /* ... */ } 

De tweede controle is nodig omdat sommige waarden geëvalueerd zijn met isset() zal resulteren in false ondanks dat de index bestaat.

Answer

Ik “gebruik dit in een project van mij, maar ik” Ik gebruik null als een gedempte toestand. (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; } 

Het is een functie die een path in een boomstructuur opzoekt.

echo option_select([A=>[B=>[C=>"hello world"]]], "NO?", "A", "B", "C"); 

Zoals je kunt zien. Ik “m loop door de waarden over een array: path. In het begin stel ik een cursor in als verwijzing naar een array waarin ik moet zoeken. Elke keer dat ik een new -toets vind, stel ik de referentie van de cursor in op de huidige sleutel waar ik naar zoek. Als je xdebug en een goede GUI hebt, kun je deze herschrijven naar het gewenste algoritme. Het is de isset($cursor[$key]) je moet veranderen. Of injecteer het als een functie: f($cursor, $key, $default) => (bool)

Opmerkingen

  • Je hebt een alternatieve oplossing gegeven maar hebt de code niet beoordeeld. Voeg alsjeblieft uitleg toe waarom dit een betere oplossing zou zijn voor het OP, in plaats van wat ze al hebben.
  • Omdat het niet ' t sterk getypt SirPython is. Op deze manier kan ik het testen met unit tests, zonder een unit test te maken voor elke ' hardcoded-string '. Dat geldt ook voor testbaarheid en de snelheid waarmee ik werkende code kan maken.

Answer

Ik was op zoek naar een vergelijkbare zelf oplossing en bedacht dit. Werkt om te bepalen of de sleutel überhaupt is ingesteld – en zal TRUE retourneren, zelfs als de waarde van de “action” -sleutel NULL is.

if (isset($array["message"]) && array_key_exists("action",$array["message"])) { /* ... */ } 

If $array["message"] heeft geen sleutels, de isset zal FALSE teruggeven en de IF-instructie stoppen. Als $array["message"] sleutels heeft – zelfs sleutels met NULL-waarden – retourneert isset TRUE, zodat u veilig kunt controleren of de "action" arraysleutel bestaat in $array["message"].

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *