Benjamin: Multidimensionale Arrays und count / sizeof

Hallo,

ich habe ein mehrdimensionales Array, bei dem ich in einer bestimmten "Tiefe" die Größe per count/sizeof ermitteln möchte. Allerdings weiß ich nicht, wie ich das realisieren kann.

Ich möchte nicht Folgendes erreichen:
"<?php
$food = array('Obst' => array('Orange', 'Banane', 'Apfel'),
              'Gemüse' => array('Karrotte', 'Kohl', 'Erbse'));

// rekursiv zählen
echo count($food, COUNT_RECURSIVE); // gibt 8 aus

// normales zählen
echo count($food); // gibt 2 aus
?>"

Um es an diesem Beispiel zu erklären: ich möchte lediglich die Größe des Arrays unter dem Index 'Obst' ermitteln...

Vorab vielen Dank für die Antworten und viele Grüße
Benjamin

  1. Hallo Benjamin,

    Um es an diesem Beispiel zu erklären: ich möchte lediglich die Größe des Arrays unter dem Index 'Obst' ermitteln...

    count ($food['Obst'])

    Viele Grüße,
    Christian

    1. Danke für die Antwort, allerdings habe ich leider das Beispiel etwas unpassend gewählt...
      Ich habe ein Array in der Session gespeichert und möchte die Größe der tieferen Ebene ermitteln.
      sizeof($_SESSION['meinArray'])
      Die erste Ebene des Arrays ist assoziativ indexiert, die zweite numerisch.
      Ich würde mich über weitere Hilfe freuen.

      1. Hallo,

        Danke für die Antwort, allerdings habe ich leider das Beispiel etwas unpassend gewählt...
        Ich habe ein Array in der Session gespeichert und möchte die Größe der tieferen Ebene ermitteln.
        sizeof($_SESSION['meinArray'])
        Die erste Ebene des Arrays ist assoziativ indexiert, die zweite numerisch.
        Ich würde mich über weitere Hilfe freuen.

        Das geht so ohne weiteres nicht. Warum? Weil in PHP es eigentlich keine mehrdimensionalen Arrays gibt. Mehrdimensionale Arrays werden in PHP nämlich so realisiert, dort Arrays wieder als Elemente des äußeren Arrays genommen werden. Die können auch andere Größe haben, zum Beispiel:

        $array = array (  
          array (1, 2, 3),  
          array (4, 5, 6, 7)  
        );
        

        Wenn Du programmiertechnisch sicherstellen kannst, dass die immer die gleiche Größe haben, dann kannst Du folgenden Code verwenden, um die "innere Dimension" zu bestimmen (ansonsten ist "innere Dimension" schlicht nicht definiert):

        $schluessel = array_keys ($_SESSION['meinArray']);  
        if (!count ($schluessel)) {  
          // $_SESSION['meinArray'] ist in der ersten Ebene leer, also kann  
          // nicht bestimmt werden, wie viele Einträge in der zweiten Ebene  
          // wären...  
          $anzahl = null;  
        } else if (!is_array ($_SESSION['meinArray'][$schluessel[0]])) {  
          // Der erste Schluessel von $_SESSION['meinArray'] ist keinem Array  
          // zugeordnet, also gibt's auch keine Anzahl Elemente...  
          $anzahl = null;  
        } else {  
          $anzahl = count ($_SESSION['meinArray'][$schluessel[0]]);  
        }
        

        Alternativ kannst Du auch sowas wie

        $anzahl = count (first ($_SESSION['meinArray']));

        machen, das ist kürzer, allerdings stellt das den internen Positionszeiger von $_SESSION['meinArray'] um (was OK ist, wenn Du weißt, was das heißt, siehe halt die Doku zu first(), next(), key(), reset(), etc.) und hat keine Überprüfungen drin (was OK ist, wenn Du programmiertechnisch sicherstellst, dass der Array immer gültig und die richtige Form hat).

        Viele Grüße,
        Christian

        1. echo $begrüßung;

          Alternativ kannst Du auch sowas wie
          $anzahl = count (first ($_SESSION['meinArray']));
          machen, [...] siehe halt die Doku zu first(), [...]

          Ich wollte mich schon freuen, dass es eine eindeutig benannte Funktion gibt, die ich bisher übersehen habe, andererseits wollte ich mich wundern, warum es nun eine neue Funktion gibt, deren Funktionalität man bisher auch gut mittels reset() bekommen hat, aber dann suchte ich die Dokumentation zu first(), doch leider vergebens ...

          echo "$verabschiedung $name";

          1. Hallo dedlfix,

            Alternativ kannst Du auch sowas wie
            $anzahl = count (first ($_SESSION['meinArray']));
            machen, [...] siehe halt die Doku zu first(), [...]

            Ich wollte mich schon freuen, dass es eine eindeutig benannte Funktion gibt, die ich bisher übersehen habe, andererseits wollte ich mich wundern, warum es nun eine neue Funktion gibt, deren Funktionalität man bisher auch gut mittels reset() bekommen hat, aber dann suchte ich die Dokumentation zu first(), doch leider vergebens ...

            Oh, dann hab ich das gerade mit einer anderen Programmiersprache verwechselt, ok, dann muss das natürlich heißen:

            reset ($_SESSION['meinArray']);  
            $anzahl = count (next ($_SESSION['meinArray']));
            

            Viele Grüße,
            Christian

            1. Hello,

              Oh, dann hab ich das gerade mit einer anderen Programmiersprache verwechselt, ok, dann muss das natürlich heißen:

              reset ($_SESSION['meinArray']);

              $anzahl = count (next ($_SESSION['meinArray']));

                
              Es müsste auch reichen  
                
                $anzahl = count(reset($\_SESSION['meinArray']));  
                
                ist ausprobiert und laut Manual auch logisch...  
                
                
                
                
              Harzliche Grüße vom Berg  
              <http://bergpost.annerschbarrich.de>  
                
              Tom
              
              -- 
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen  
              Nur selber lernen macht schlau  
              Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)  
                
              ![](http://bitworks.de/~selfHTML/Virencheck.gif)  
              
              
              1. Hi,

                reset ($_SESSION['meinArray']);

                $anzahl = count (next ($_SESSION['meinArray']));

                
                >   
                > Es müsste auch reichen  
                >   
                >   $anzahl = count(reset($\_SESSION['meinArray']));  
                >   
                >   ist ausprobiert und laut Manual auch logisch...  
                  
                nein, es ist beides falsch, da nicht berücksichtigt wird, ob das Array evtl. leer ist. Falls dies so ist, liefern sowohl reset() als auch next() boolean false und count(false) liefert 1, was in diesem Fall aber nicht erwünscht sein dürfte.  
                  
                Gruß,  
                Andreas.
                
                1. Hallo Andreas,

                  reset ($_SESSION['meinArray']);

                  $anzahl = count (next ($_SESSION['meinArray']));

                  
                  > >   
                  > > Es müsste auch reichen  
                  > >   
                  > >   $anzahl = count(reset($\_SESSION['meinArray']));  
                  > >   
                  > >   ist ausprobiert und laut Manual auch logisch...  
                  >   
                  > nein, es ist beides falsch, da nicht berücksichtigt wird, ob das Array evtl. leer ist.  
                    
                  Ja, Du hast natürlich Recht, aber das schrieb ich zur Lösung bereits dazu, dass da Überprüfungen fehlen, dass das äußere Array ausreichend viele Elemente hat.  
                    
                  Wobei Tom natürlich recht hat, dass es besser und kürzer ist, den Rückgabewert von reset() zu nutzen, wenn man schon diesen Weg einschlägt.  
                    
                  Viele Grüße,  
                  Christian  
                  
                  
                  1. Hi,

                    aber das schrieb ich zur Lösung bereits dazu, dass da Überprüfungen fehlen, dass das äußere Array ausreichend viele Elemente hat.

                    ich meinte die inneren Arrays, wo es nicht genügt zu prüfen/vorauszusetzen, dass die Anzahl der Elemente immer gleich ist, sondern sie muss auch größer 0 sein, damit man nicht 1 als Ergebnis bekommt. Allerdings habe ich in der Tat überlesen, dass du bereits auf die Gültigkeit des Arrays hingewiesen hast. Und leere Arrays wären nach der Aufgabenstellung auch ziemlich sinnfrei ;)

                    Gruß,
                    Andreas.

                2. Hello,

                  reset ($_SESSION['meinArray']);
                  $anzahl = count (next ($_SESSION['meinArray']));

                  Es müsste auch reichen

                  $anzahl = count(reset($_SESSION['meinArray']));

                  ist ausprobiert und laut Manual auch logisch...

                  nein, es ist beides falsch, da nicht berücksichtigt wird, ob das Array evtl. leer ist. Falls dies so ist, liefern sowohl reset() als auch next() boolean false und count(false) liefert 1, was in diesem Fall aber nicht erwünscht sein dürfte.

                  Gut, dass Du darauf hinweist.
                  Ich hatte vorhin zufällig gerade einen größern Array-Test auf dem Schirm für mein kleines PHP-Handbuch "Die Grenzen ausreizen"...

                  Für die hiesige Fragestellung hatte ich allerdings einfach vorausgesetzt, dass man bereits weiß, dass die benutze Variable existiert und ein Array ist. Faulheit rächt sich aber!

                  Ich empfehle daher, aufgrund Deiner Ermahnung und der Versuche, die ich ja eigentlich garade nochmal wiederholt habe:

                  Bevor man in PHP mit einem Arrayelement irgendetwas anfängt, sollte man überprüfen,
                     ob es überhaupt definiert ist und ob es wirklich ein Array ist.

                  Anderenfalls gibt es erstaunliche Ergebnisse und leider selten eine Warnung / Notice.
                  Ich habe es auch schon mehrmals geschafft, durch entsprechende (falsche) Array-Operationen den Apachen (also sein PHP-Modul) zum Absturz zu bringen. Das Ding hat anschließend nur noch Quatsch gemacht.

                  Besonders gut klappt das durch Zuweisung eines Arrays auf einen im Array gespeicherten Skalar.
                  Aber auch die implizite Deklaration führt hier manchmal zum "Erfolg"

                  $_data['Hansen'] = "Hans";
                  $_data['Piller'] = "Paul";
                  $_data['Fröhlich'] = "Fritz";
                  $_data['Lummer'] = "Lieselotte";
                  $_data['sorglos'] = "Sabine";

                  $_data['Fröhlich']['Adamski'] = 'Abraham';  ### Fehler! Subelement muss vorhanden sein

                  Auf jeden Fall kommt dummes Zeug dabei heraus...

                  Eigentlich sollte das zumindest einen Fehler geben. wahlweise

                  • warning: cannot redeklare Index imlicit
                  • notice: index not found

                  oder sonstwas schlaues.

                  Man bekommt den  Server damit jedenfalls aus dem Tritt und ich befürchte, dass das auch über den Weg $_POST, $_GET, $_COOKIE funktioniert. Soweit bin ich aber noch nicht vorgedrungen.

                  Harzliche Grüße vom Berg
                  http://bergpost.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau
                  Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                  1. echo $begrüßung;

                    $_data['Fröhlich'] = "Fritz";
                    $_data['Fröhlich']['Adamski'] = 'Abraham';  ### Fehler! Subelement muss vorhanden sein
                    Auf jeden Fall kommt dummes Zeug dabei heraus...

                    Ja, es steht dann "Aritz" in $_data['Fröhlich'].

                    Eigentlich sollte das zumindest einen Fehler geben. wahlweise

                    Gibt es aber nicht, weil hier PHPs automatische Typumwandlung zusammen mit String access and modification by character zuschlägt. Du hast einen String "Fritz" vorliegen. Auf dessen Zeichen kann man mit [index] zugreifen. "Fritz"[0] ist also das F. Da für den Index nur Zahlen verwendet werden können, wandelt PHP das 'Adamski' in eine Zahl um. Gemäß den Typecast-Regeln für Strings ergibt (int)'Adamski' also 0. Da man ein Zeichen nur mit einem anderen Zeichen, nicht aber mit mehreren überschreiben kann, wird nur das A von 'Abraham' genommen und ersetzt das F.

                    (Ja, ich weiß, "Fritz"[0] ist keine gültige PHP-Syntax. Statt "Fritz" muss eine Variable stehen.)

                    echo "$verabschiedung $name";