PHP: Ermitteln ob ein Array mehrere Unterarrays besitzt

Saugkraft

Saugkraft

Aktives Mitglied
Thread Starter
Dabei seit
20.02.2005
Beiträge
8.998
Reaktionspunkte
3.189
Moin Leute,

ich bekomme von einem Webservice als Rückgabe ein Array mit Werten. Je nachdem, wieviele Werte zurückgeliefert werden, ist das Array unterschiedlich aufgebaut:

Variante 1 (mehrere Werte):
Code:
[instances] => Array (
[instance] => Array (
[0] => Array (
[@attributes] => Array (
[id] => 12345
[name] => 'Miller')
)
[1] => Array (
[@attributes] => Array (
[id] => 23456
[name] => 'Smith')
)
))

Variante 2 (ein Wert):
Code:
[instances] => Array (
[instance] => Array (
[@attributes] => Array (
[id] => 12345
[name] => 'Miller')
))

Im Fall 1 enthält das Array "instance" also wieder mehrere Arrays [0],[1],.. mit einem Array @attributes.
Im Fall 2 enthält das Array "instance" das Array @attributes.

Wenn ich das in PHP parsen will und benutze foreach ($array as $user) und frage den Wert $user['name'] ab, dann funktioniert das in Fall 1 aber nicht in Fall 2.

Das Problem ist, ich weiß nicht, was mir zurückgeliefert wird. Fall 1 oder 2.

Die Frage: Wie kann ich das am besten ermitteln wenn das Array wie oben aufgebaut ist?

Irgendwie stehe ich da gerade auf dem Schlauch. :hum:
 
teste doch mit is_array bevor du auf den wert zugreifst.
 
Ihr sagt das so leicht. :D

is_array — Prüft, ob die Variable ein Array ist
Ich hab aber in dem Moment noch keine Variable.

Wenn ich prüfe, ob [instance] (oder das darunter) ein Array ist, bekomme ich in jedem Fall ein true.

Fall 1:
[instance] => Array (
[0] => Array (
[@attributes] => Array (

Fall 2:
[instance] => Array (
[@attributes] => Array (

Sind beides Arrays. :noplan:

Abgesehen davon hat is_array einen völlig anderen Zweck.
 
ist eh schwierig in pseudo code zu erklären.
du machst doch irgendwo im code den zugriff auf 'name', den wert holst du doch aus deinen arrays da …
bevor du das machst, kannst ja mit is_array prüfen, ob du da jetzt einen wert hast oder ein array …
 
Eben. irgendwo muss es ja unterschiedlich sein.

Sonst vielleicht hiermit? http://us.php.net/count
Da ist explizit sogar ein multidimensionales array drin. Boah, bin ich froh das ich kein php mache.
 
ist eh schwierig in pseudo code zu erklären.
du machst doch irgendwo im code den zugriff auf 'name', den wert holst du doch aus deinen arrays da …
bevor du das machst, kannst ja mit is_array prüfen, ob du da jetzt einen wert hast oder ein array …
Ja na klar. Das löst das Problem "obendrüber" aber logisch nicht.

Wenn ich auf name zugreifen will, dann muss ich erstmal in den Bereich absteigen, in dem das Attribut Name auftaucht. Das ist aber im x-ten Unterarray. Bis ich dahin abgestiegen bin und Arrays abklappere, habe ich schon einen Fehler.

Ich komme doch gar nicht dahin, weil ich die Anzahl der Arrays nicht kenne.

Abstrahiert:

Ich habe ein Array mit x Unterarrays, in denen sich irgendwo ein Wert befindet.

array1 -> array2 -> array3 -> array4 -> attribut

alternativ:

array1 -> array2 -> attribut

oder..

Gut, ich kann jetzt rekursiv durch die Arrays wandern und auf jeder Ebene prüfen, ob es ein Array ist. Falls nicht, nehme ich das letzte Array, in das ich abgestiegen bin und lese das Attribut aus.

Dazu kann ich mir auch eine Klasse schreiben, die mir die Tiefe des Arrays zurückliefert. Die Kröte würde ich aber ungerne schlucken. So hab ich vor gefühlten 5 Jahren programmiert. Und da war ich schon spät dran. :D

Vielleicht verstehe ich die Logik auch einfach nicht, warum jemand bei einem Webservice eine zusätzliche Ebene einführt wenn es mehrere whatever gibt. Ich meine wer zählt denn so? :noplan:

Die Anzahl der Arrays unterhalb von instance ist x. x kann 0, 1 oder größer 1 sein.

Wenn ich einen Webservice schreibe, liefere ich zurück:
[null]
oder
[0]
oder
[0]
[1]
..

Wobei die dritte Ausgabe logisch die gleiche wie die zweite ist.

Vielleicht gibt es für den Blödsinn einen Grund, den ich noch nicht verstehe. :(

Aber für mich gibt es zwischen if (a==0) und if(!a) und isset(a) immer noch einen Unterschied.

Da ist explizit sogar ein multidimensionales array drin. Boah, bin ich froh das ich kein php mache.
Zum einen kommt der Scheiß aus Tomcat und nicht aus php :D, zum anderen nützt mir count nicht viel, weil für die Abfrage von count eine Menge da sein müsste, die ich eingrenzen kann.

Kein PHP? Was denn sonst so?* Ich nehme auch gerne eine Lösung in jeder anderen Sprache. Ich sag immer gerne.. Kannst du eine gut, gehen die anderen auch. :hehehe:

*Java oder noch schlimmer? Java hat einen großen Vorteil. Seit Java gibt es das Berufsfeld des Java-Debuggers. Der verdient mehr, arbeitet länger und hat komplexere Aufgaben als die Programmierer. :D

**Jeder Java Programmierer im Forum hat jetzt mindestens einen PHP Witz frei.
 
@xentric Jaja, wenn man nicht weiterweiss ist immer PHP schuld. Ich kann den Unfug schon lange nicht mehr hören.


@Saugkraft , wenn Du weisst das es ein array ist (siehe oben) kannst Du danach mit array_key_exists prüfen ob der Key in dem array vorhanden ist.

Die Struktur ist in der Tat etwas strange. Da kann ich Deinen Unmut verstehen, aber nein...ich lass mich jetzt nicht zu nem Spruch über Java hinreissen :crack:
 
Ach komm... Einen Spruch.. bitte. Nur einen kleinen. :crack:

Naja klar, ich kann ja auch prüfen, ob im Array [instance] der key [0] existiert. Wenn nicht müsste es ein Array mit einer Ebene weniger sein. Mich stört das müsste. Eine Gegenprobe wäre dann schon das mindeste. Sprich: Falls der key [0] im Array nicht existiert, müsste der nächste bei dem Aufbau [@attributes] sein.

Das kann ich natürlich abbilden. Für den Webservice gibt es schon eine Klasse, von daher kann ich natürlich bei der Abfrage noch 1000 Dinge prüfen.

Unmut.. Naja.. Mh. Geht so. ich finde es einfach nicht sauber.

1. Prüfe, ob die Zusatzebene existiert. Das mache ich, indem ich mit dem Stock im Teich rumstochere.
2. Wenn du auf was festes stößt, nimm den kurzen Stock, wenn nicht, nimm den langen.
3. Stochere mit dem passenden Stock weiter und drück die Daumen, dass es nicht noch ein anderes Problem gibt.

Und ja.. ich bin pingelig. :hehehe:
 
Stimmt schon, es ist immer undankbar so einen Array-Salat nach was solidem wie JSON oder XML Parsen zu müssen. Kann man da am liefernden Service nichts ändern?
 
Kann man da am liefernden Service nichts ändern?
Ich hab bei Adobe schon angefragt. Aber die erwarten Kennwörter über die API auch im Klartext. Was willst du da noch sagen? :crack:

Naja, im aktuellen Fall werd ich nach gefühltem Gefühl :D im Array [instance] mit array_key_exists auf [0] prüfen und dann entweder foreach oder gleich die Werte abfragen.

Elegant ist anders aber es gibt schlimmeres. :)

Ich hatte heute wieder das Vergnügen mit den Java Kollegen..

Problem 1 wurde beantwortet mit: Dazu muss ich die Bibliothek einbinden.. ob das ich das kann.. dann müssen wir die App nochmal deployen..
Problem 2 mit: Ich sehe da keinen Fehler, sieht alles plausibel aus.

Daraufhin hab ich mir den Quelltext der Methoden mal schicken lassen und das Problem in 5 Minuten eingegrenzt, obwohl Java für mich Fremdsprache ist.

Ich glaube aber, wir wollten gar nicht über Java ablästern, oder? :suspect: :hehehe:
 
  • Gefällt mir
Reaktionen: wegus
naja, wenn du pingelig bist, musst du doch eh die gelieferten daten validieren, bzw abstürze durch nicht konforme daten verhindern …
 
Ich glaube aber, wir wollten gar nicht über Java ablästern, oder? :suspect: :hehehe:
Schlechtes API Design geht doch in jeder Sprache prima, das muss man nicht auf Java eingrenzen. Ich kann das auch mit PHP ;-)
 
  • Gefällt mir
Reaktionen: wegus
Schlechtes API Design geht doch in jeder Sprache prima, das muss man nicht auf Java eingrenzen. Ich kann das auch mit PHP ;-)
Stimmt. Mit Java kannst du das aber schneller, besser und vor allem nachhaltiger. :hehehe:

naja, wenn du pingelig bist, musst du doch eh die gelieferten daten validieren, bzw abstürze durch nicht konforme daten verhindern …
Natürlich muss ich das. Es ist aber deutlich leichter, je valider die Daten sind.

Meine Frage war: Gibt es in PHP eine Möglichkeit, das Problem valide ohne Q&D zu lösen?

Alternativ: Wie sehen das meine Kollegen? Klasse? Iterieren? Q&D?

Bei allem Respekt.. Pseudocode hin oder her.. so richtige Antworten auf Augenhöhe (wegus nehme ich da mal aus, weil ich weiß, was er kann) hab ich jetzt nicht wirklich bekommen. Da kann ich auch bei ... nachlesen.
 
Nachtrag..

Nimm es mir bitte persönlich nicht übel oneOeight. Du bist ein alter erfahrener Sack und was du in diesem/für dieses Forum geleistet hast, kann man dir gar nicht bezahlen.

Aber:
Array [instance] mit array_key_exists auf [0] prüfen und dann entweder foreach oder gleich die Werte abfragen.
Das war jetzt meine Leistung zu meiner Frage.

Ab und zu rede ich mit "fachfremden" (=> andere Sprache) Kollegen sehr gerne. Gibt immer ein bisschen Input und ich kann meinen Horizont erweitern.

Bekommen habe ich: "Did you try to turn it off and on again?"

:blowkiss:
 
Mag ja sein, dass ich das eigentliche Problem verkenne. Aber wenn ich mir Dein Beispiel so ansehe, so ist das doch gar nicht soooo komplex!?

Instances enthält ein Array instance und das enthält n arrays mit dem Unterarray aus attributes und [id,name]

Der Aufbau gilt pauschal (fast) immer. Einzig den Sonderfall mit nur einem Instance-Array haben die versaubeutelt und tragen das dann direkt ein (also ohne Index 0). Wenn Dein Beispiel repräsentativ für alle Datensätze ist, mußt Du doch nur den Sonderfall abprüfen und wenn der nicht gilt, kannst Du doch von dem Aufbau aus Deinem ersten Beispiel ausgehen und über das array of arrays iterieren !? Oder was sehe ich da jetzt nicht?
 
(also ohne Index 0).
Genau der. Das ist relativ unglücklich gelöst.

Und na klar kann ich den Sonderfall abprüfen. Ich denke, dass der beste Weg dann array_key_exists (0) wäre. Wenn ja, iteriere durch das Array, falls nicht, ruf die Werte ab. Das hab ich mir jetzt so überlegt. is_array bringt da nicht weiter.

Ich mag halt diese Inkonsistenzen nicht, weil du nach 14 Monaten und x-tausend weiteren Zeilen Quellcode irgendwo eine Ausnahme stecken hast, die du dann erst mal wieder ausgraben musst.

Eine Klasse, die mit if.. irgendwas prüft, ist mir immer suspekt. Da bin ich Spießer. :D

Naja, jammern hilf nix. Werde ich dann so machen. Ich hatte gehofft, dass PHP da irgendwas bequemes hat. Ich komme tendenziell aus der ASP Ecke und bequem ist da eigentlich nur, dass alle Befehle auf einen DIN A7 Zettel passen. :crack:
 
ist das beispiel im ersten post nicht überhaupt missverständlich?
variante 1 listet halt die unter-arrays mit index auf, variante 2 liefert halt nur über den einzelen schlüssel, wobei das natürlich, wenn es ein array ist, auch einen index haben sollte.
normal sollte dann der sonderfall (gibt es den überhaupt? darstellung variante 2 korrekt?) doch über count von instance prüfbar sein bzw stumpf über den index iterierbar sein.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: wegus
Eine Klasse, die mit if.. irgendwas prüft, ist mir immer suspekt

Öhm...aha! Du hast doch hier aber einen Sonderfall und den wirst Du abprüfen müssen. Sicher kannst Du die if-clause umlaufen in dem Du einfach den Sonderfall generalisierst und eine Schleife drüber laufen läßt die dann ggf. nur 0 oder einmal ausgeführt wird. Das aber finde ich dann inplausibler als eine eindeutige und leicht nachvollziehbare if-clause.
 
variante 1 listet halt die unter-arrays mit index auf, variante 2 liefert halt nur über den einzelen schlüssel, wobei das natürlich, wenn es ein array ist, auch einen index haben sollte.
Hat es ja nicht. Das ist das Problem. Alles andere ist "Kinderkacke". Das Problem ist die Inkonsistenz, dass Variante 1 einen Index liefert, 2 nicht.

wegus: Das lass ich nochmal sacken.

Ich würde das "spezielle" Problem gerne auf eine etwas behandelbare Ebene heben. Die Kollegen bei Adobe haben es (IMHO) nicht gut gelöst, jetzt würde ich einfach einen "unfehlbaren" Service oben drauf setzen.
 
Zurück
Oben Unten