Portal > Foren > PHP > PHP-Programmierung > Schlüssel in verschachteltem Array suchen und Wert zurückgeben
Antwort
 
Themen-Optionen Thema durchsuchen
Alt 18.10.2006, 13:40 Nach oben    #1
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.480
Standard Schlüssel in verschachteltem Array suchen und Wert zurückgeben

Hi,
ich habe folgende Methode
PHP-Code:
    /**
     * Die Methode gibt einen bestimmten Konfigurationswert zurück, welcher 
     * durch den Namen des Konfigurationspunkts bestimmt wird.
     * 
     * Existiert der Arrayschlüssel nicht, so wird eine 
     * {@link ArrayIndexDoesNotExistException ArrayIndexDoesNotExistException} geworfen.
     * 
     * @param string  $option  Name der Konfigurationsangabe
     * @param array   $config  Konfigurationsarray
     * @return string  Wert der Konfigurationsangabe 
     * 
     * @throws ArrayIndexDoesNotExistException
     */
    
public function get($option, array $config null)
    {
        if(
is_null($config))
        {
            
$config $this->config;
        }

        if(
array_key_exists($option$config))
        {
            return 
$config[$option];
        }   
        
        foreach(
$config as $key => $value)
        {
            if(
is_array($value))
            {
                return 
$this->get($option$value);
            }
                       
        }
        
        throw new 
ArrayIndexDoesNotExistException($config);
    } 
Jut.
Dazu gehört folgendes Array ($this->config)
Code:
array(9) {
  ["database"]=>
  array(6) {
    ["host"]=>
    string(9) "localhost"
    ["user"]=>
    string(4) "root"
    ["password"]=>
    string(0) ""
    ["dbname"]=>
    string(6) "test"
    ["tableprefix"]=>
    string(6) "xy__"
    ["dbtype"]=>
    string(5) "mysql"
  }
  ["general"]=>
  array(1) {
    ["option"]=>
    string(10) "value"
  }
}
Ich will den Wert eines Arrayschlüssels zurückgeben, unabhängig davon, in welcher Arrayebene dieser vorkommt.
Als Basis habe ich das hier verwendet:
http://de2.php.net/manual/en/functio...ists.php#66791

Ich erhalte nun aber generell eine ArrayIndexDoesNotExistException.

Das ist ein klassischer Denk-Logikfehler, aber ich steh mal wieder auf dem Schlauch und seh es einfach nicht ...

*vorsorglich an den Kopp hau*

Danke für Eure Hilfe.
Grüße, Ben.


[Nachtrag]
Wenn ich die Exception auskommentiere erhalte ich einfach gar keinen Wert.
Liegt halt daran, dass ich am Ende nochmals die Methode rekursiv aufrufen müsste, da ja nach dem ersten "inneren" Array ans Ende der Methode "gelaufen" wird und dann .. jou, is eben Ende.
Problem ist nur irgendwie ..
1. wie ruf ich denn dann die Methode auf? Mir scheint, dass die for-each-Schleife nicht ganz ihren Zweck erfüllt. :-/
2. Wie baue ich die Abbruchbedingung ein bzw. wann schmeiße ich die Exception?

Datt kann doch eigentlich nicht so schwer sein ..

Geändert von Ben (18.10.2006 um 14:09 Uhr).
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2006, 16:04 Nach oben    #2
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Ja ne. Du musst in der foreach-Schleife den Wert, der zurückkommt speichern und ein return nur ausführen, wenn ein Wert gefunden wurde. Andernfalls muss eben null zurückgegeben werden - aber erst nach der Schleife.

Die Exception kann so nicht stehen bleiben, es sei denn, du fängst sie in der foreach-Schleife ab, um sie nicht nach außen durchsickern zu lassen.

PHP-Code:
    public function get($option, array $config null)
    {
        if(
is_null($config))
        {
            
$config $this->config;
        }

        if(
array_key_exists($option$config))
        {
            return 
$config[$option];
        }   
        
        foreach(
$config as $key => $value)
        {
            if(
is_array($value))
            {
                
$result $this->get($option$value);
                if (!
is_null($result)
                    return 
$result;
            }
        }
    } 
Wenn du wirklich eine Exception willst, dann kann ein return erst erfolgen, wenn ei Wert gefunden wurde oder alle Felder durchsucht wurden und definitiv kein Wert da ist. Da du aus den inneren Schleifen ja aber wieder rauskommen must, ohne Exception, auch wenn die keinen passenden Wert enthalten, musst du die Schleifen irgendwie unterschiedlich markieren. Kannst also bei einem rekursiven Aufruf z.B. einen dritten Parameter auf true setzen oder eine Statische Variable setzen, die vor dem endgültigen Return bzw. der Exception wieder gelöscht wird.

Aber mal eine Generelle Frage:
Was macht das für einen Sinn? Wozu überhaupt ein verschachteltes Array, wenn du damit nicht verschiedene Namensräume schaffst?

Basti

PS:
Das $key in dr Schleife kannst du weglassen und dass ein Type-Hinting für Arrays möglich ist, hab ich bisher übersehen ... cool ... fehlen ja nicht mehr viele Typen. *g

Geändert von Basti (18.10.2006 um 16:06 Uhr).
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2006, 16:16 Nach oben    #3
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.480
Standard

Ohweia.
Jou, alles klar. Die Exception streich ich.

Bzgl. Sinn eines verschachtelten Arrays:
Im Voraus .. ich lass mich gerne belehren.

Die Daten sind Konfigurationsdaten, welche durch diese Methode get($key) verfügbar gemacht werden sollen. Da die Einstellungen aber gruppiert vorkommen (für die Anzeige im ACP) dachte ich mir, dass das eine ganz nette Möglichkeit wäre.

Deine Frage lässt mich nun aber zweifeln .. .. eigentlich wäre es ja viel günstiger ein "flat array" mit nur eine Dimension zu erstellen und die gruppierte Speicherung bzw. Darstellung anderweitig zu erledigen.

Joa, klar. Logo .. das eine hat ja mit dem anderen gar nichts zu tun.
Hehe .. .. joa.
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2006, 16:29 Nach oben    #4
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Ne, ich würd die schon gruppiert lassen. Kommt natürlich drauf an, was du da baust. Aber wenn das Ding erweiterbar sein soll, kannst du so den Erweiterungen einfach neue Namensräume geben. Andernfalls wird es schwierig Konflikte auszuschließen:

Jemand programmiert ein Modul, um einen bestimmten Webservice abfragen zu können. Dafür braucht es aber Zugangsdaten in der Konfig. Hier das Feld für den Benutzernamen einfach user oder service_user zu nehmen, kann Konflikte bringen. Sinniger, wenn einfach nur das Modul einen eindeutigen Namen hat (brauchts ja eh) und ein eigenes Unter-Array $config[<modulname>] bekommt. Damt reduzierst du das Konfliktfeld tatsächlich nur auf den Modul-Namen.

Das lässt sich natürlich auch mit einem Unterstrich lösen: mysql_user. Aber die Variante mit den Arrays hat noch mindestend zwei weitere Vorteile:

1. Kannst du das Config-Array eines Moduls (dazu unabhängig von dessen Namen) in einer eigenen Datei abspeichern und kannst beim Zugriff die entsprechende Datei dynamisch nachladen falls sie noch nicht geladen wurde, ohne den Wert erst auseinanderpflücken zu müssen ($modul = substr($option, 0, strpos($option, '_')) oder so ähnlich).

2. Kannst du eventuell - falls deine Architektur das hergibt - jeder Komponente nur ihre eigene Konfiguration zugänglch machen. Der eigenliche Aufruf wäre also $Config->get($module, $option), aber beim "Betreten" eines Moduls könnte der Wert $modul ja auch festgesetzt werden - auf einem Stapel im Config-Array, der beim "Verlassen" des Moduls wieder abgebaut wird.

Genauso kannst du z.B. auch mit den Requests verfahren - so dass jede Komponentenur die Requests zu Gesicht bekommt, die sie auch betreffen.

Noch einer:
Du kannst die Config eines Moduls geschlossen auslesen: array $Config->get($module); und so z.B. ein Control-Panel anbieten, das nicht "hardcodet" ist, sondern einfach alle Werte mit je einem Eingabefeld auflistet.

Basti

Geändert von Basti (18.10.2006 um 16:33 Uhr).
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2006, 16:56 Nach oben    #5
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.480
Standard

Yeah. Cool. Fein. *freu* *gg* ..
Da werd ich mal drüber nachdenken.

Das ist eigentlich ja das, was ich gesucht habe .. irgendwie .. über Umwege da hingelangt, aber egal.
Danke erstmal.
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.10.2006, 06:28 Nach oben    #6
Lutz
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 684
Standard

Da mir das jetzt doch zuviel Text wurde für dieses doch recht kleine Problem, wollte ich nur mal anmerken, dass es so garnicht funktionieren KANN, denn sobald das erste Array beim Durchlaufen gefunden wird, springst du aus der Schleife mit dem return raus.
Dazu kommt noch, dass du bei jedem Funktionsaufruf die Exception startest, wenn der Key nicht gefunden wurde, was logischerweise jedesmal zu einer Exception führt, wenn das Array keinen Wert enthält.

Ich hoffe, ich habe hier jetzt niemanden wiederholt.

Funktionieren dürfte deine Schleife folgendermaßen:

PHP-Code:
public function get($option, array $config null)
{
  if (
is_null ($config) === TRUE)
  {
    
$config $this->config;
    
$exception TRUE;
  }

  if (
array_key_exists ($option$config) === TRUE)
  {
    return 
$config[$option];
  }   
  
  foreach (
$config AS $key => $value)
  {
    if (
is_array ($value) === TRUE)
    {
      
$result $this->get ($option$value);
      
      if (!
is_null ($result) === TRUE)
      {
        return 
$result;
      }
    }
  }
  
  if (
$exception === TRUE)
  {
    throw new 
ArrayIndexDoesNotExistException($config);
  }
  
  return 
NULL;

Die Exception wird also nur beim ersten Durchlauf aufgerufen, sofern $config nicht definiert wird. Keine saubere Geschichte, funktioniert aber.

Ansonsten habe ich mich an deiner Funktion und an der von Basti orientiert.

Fraglich ist aber weiterhin, ob es nicht eher Sinn macht mit array_keys() zu arbeiten und das Array mittels Callback (array_walk_recursive()) zu durchlaufen!?
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.10.2006, 12:14 Nach oben    #7
Bastian Fenske
 
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 826
Standard

Sauberer wäre eben, die Exception in der foreach-Scchleife abzufangen, so dass eben nur die Exception des ersten Durchlaufs nach draußen geworfen wird.

Aber an sich eine interessante Idee, eine Antwort nicht zu lesen, weil sie zu lang sei und die Frage einfach nochmal zu beantworten - mit auch nicht weniger Text. Warum auch nicht? *g

Basti
Basti ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.10.2006, 18:49 Nach oben    #8
Lutz
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 684
Standard

@Basti: Sorry, ich hatte einfach keine Zeit mehr, da ich zur Arbeit musste, wollte die Frage aber dennoch beantworten
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.10.2006, 18:54 Nach oben    #9
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.480
Standard

Ich sags einfach nochmal.
Danke für Eure Hilfe.

Kann das letztlich jetzt gerade nicht gebrauchen, aber trotzdem nett, zu wissen, wie es gehen würde. Hehe.
Stand da letztlich auch einfach zu fest auf dem Schlauch.

Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Array key eines bestimmten Wertes zurückgeben Ben PHP-Programmierung 9 25.06.2007 15:16
Suche Hilfe: Angebot und Nachfrage berechnen ljungi Plauderecke 6 17.12.2006 22:10
Array in Bezug auf ein anderes sortieren... code5 PHP-Programmierung 2 15.05.2006 15:56
Modifier haben einen Wert, obwohl keine gedrückt sind materthron Desktop-Applikationen und Grafik 3 06.11.2005 16:28
[PHP] Kontrollstrukturen in PHP Jann Hendrik Tutorials 7 09.12.2004 21:28


Alle Zeitangaben in WEZ +2. Es ist jetzt 21:31 Uhr.


Powered by vBulletin® Version 3.7.3 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44