Vivienne: Array

Guten Morgen,

wenn ich diesen Code unter XAMPP ausführe

	$UserMonat = $mysqli->prepare("SELECT id, userid, monat FROM buch WHERE userid = ? ");
	
	$UserMonat->bind_param("s", $userObject->userID);
	$UserMonat->execute();
	$UserMonat->bind_result($id, $userid, $monat);
	$UserMonat->store_result();
	 	
	while ($stmt->fetch()){
			$UserMonatArray[] = array( 
				'monat' => $monat
			);
		}
	echo $UserMonatArray;

var_dump($UserMonatArray);

Erhalte ich diese Ausgabe

Arrayarray(3) {
  [0]=>
  array(1) {
    ["monat"]=>
    string(2) "3"
  }
  [1]=>
  array(1) {
    ["monat"]=>
    string(1) "5"
  }
  [2]=>
  array(1) {
    ["monat"]=>
    string(1) "7"
  }
}

Ist das denn richtig? Mir kommt das alles etwas merkwürdig vor? Warum steht z.B. ganz oben Arrayarray?

Ich muss mit dieser Abfrage später die Daten an ein anderes Script übergeben, das erwartet diese Eingabe

$monate = array(3,5,7);

Wenn das alles richtig ist, wie übergebe ich denn den Wert von $UserMonat an $Monate?

  1. Tach!

    Ist das denn richtig? Mir kommt das alles etwas merkwürdig vor? Warum steht z.B. ganz oben Arrayarray?

    Das Array kommt davon, wenn man ein Array mit echo auszugeben versucht. Das array ist Teil der Ausgabe von var_dump().

    Ich muss mit dieser Abfrage später die Daten an ein anderes Script übergeben, das erwartet diese Eingabe

    $monate = array(3,5,7);
    

    Deine Ausgabe zeigt ein Array mit Arrays mit einem dem Schlüssel monat zugewiesenen Wert. Du willst aber nur ein Array mit Werten haben.

    Wenn das alles richtig ist, wie übergebe ich denn den Wert von $UserMonat an $Monate?

    Also entweder speicherst du gleich nur die Werte und nicht ein Array mit dem Wert in deinem Array ab, oder du läufst nochmal durch das Array-Array durch und erzeugst ein neues mit nur Werten. Das kann man iterativ mit foreach machen oder funktional mit array_map().

    dedlfix.

  2. Hallo

    	 	
    	while ($stmt->fetch()){
    			$UserMonatArray[] = array( 
    				'monat' => $monat
    			);
    		}
    	echo $UserMonatArray;
    
    var_dump($UserMonatArray);
    

    Erhalte ich diese Ausgabe

    Arrayarray(3) {
      [0]=>
      array(1) {
        ["monat"]=>
        string(2) "3"
      }
      [1]=>
      array(1) {
        ["monat"]=>
        string(1) "5"
      }
      [2]=>
      array(1) {
        ["monat"]=>
        string(1) "7"
      }
    }
    

    Ist das denn richtig? Mir kommt das alles etwas merkwürdig vor?

    Du packst in jedem Fetch-Durchlauf ein neues Element zum Array $UserMonatArray. Soweit, so richtig. Du packst in jedes dieser Elemente wiederum ein Array mit dem Inhalt $key = "monat" => $val = $monat hinein. Du erzeugst also ein zweidimensionales Array (ein Array mit jeweils einem Array pro Arrayelement).

    Ich muss mit dieser Abfrage später die Daten an ein anderes Script übergeben, das erwartet diese Eingabe

    $monate = array(3,5,7);
    

    Dann solltest du auch nur $monat an das Array $UserMonatArray übergeben ($UserMonatArray[] = $monat).

    Tschö, Auge

    --
    Es schimmerte ein Licht am Ende des Tunnels und es stammte von einem Flammenwerfer.
    Terry Pratchett, „Gevatter Tod“
    1. Hallo,

      Dann solltest du auch nur $monat an das Array $UserMonatArray übergeben ($UserMonatArray[] = $monat).

      wenn ich dieses mache erhalte ich diese Ausgabe

      array(3) {
        [0]=>
        string(2) "3"
        [1]=>
        string(1) "5"
        [2]=>
        string(1) "7"
      }
      

      sieht schon etwas besser aus. Was haben eigentlich die Zahlen in () zu sagen? Jetzt bleibt noch die Frage, wie ich $UserMonatArray[] = $Monat in $monate = array(3,5,7); bekomme, also die Zahlen sollen dynamisch gefüllt werden.

      1. Tach!

        Was haben eigentlich die Zahlen in () zu sagen?

        Das ist die Länge. Das Array hat 3 Elemente, die Strings jeweils 1 Zeichen (aus Sicht von ISO-8859-1) und der eine 2. Das zweite scheint unsichtbar zu sein.

        dedlfix.

        1. Hallo,

          Das ist die Länge. Das Array hat 3 Elemente, die Strings jeweils 1 Zeichen (aus Sicht von ISO-8859-1) und der eine 2. Das zweite scheint unsichtbar zu sein.

          danke für deine Erklärung. Jetzt bleibt noch die letzte Frage, wie ich $UserMonatArray[] = $Monat in $monate = array(3,5,7); bekomme, also die Zahlen sollen dynamisch gefüllt werden.

          Hab hier http://www.strassenprogrammierer.de/php-arrays_tipp_539.html etwas gelesen, allerdings egal was ich mache ich bekomme die , nicht zwischen die Zahlen.

          Wenn ich es richtig verstanden habe, muss ich zuerst ein leeres Array anlegen mit

          $Monate[] = "";

          Dann dachte ich muss es so füllen: array_push($Monate, $UserMonatArray[]);

          Aber es funktioniert nicht. Vielleicht hat jemand nochmals Zeit mir es zu erklären / zu zeigen.

          1. Hallo und guten Abend,

            danke für deine Erklärung. Jetzt bleibt noch die letzte Frage, wie ich $UserMonatArray[] = $Monat in $monate = array(3,5,7); bekomme, also die Zahlen sollen dynamisch gefüllt werden.

            Hier bindest Du drei Variablen an die Ergebnisdatensätze, die auch jeder drei Werte enthalten sollten:

                $UserMonat->bind_result($id, $userid, $monat);
            

            Und dann werden diese Variablen bei jedem Fetch()-Durchlauf damit gefüllt und stehen sofort nach dem fetch() mit den neuen Werten (aktuelle Zeile der Ergebnismenge) zur Verfügung

            
                $_monate = array();
            
                while ($stmt->fetch())
                {
                    $_monate[] = $monat;
                } 
            
            

            Im Array $_monate sollte sich jetzt die Spalte monat aus dem Ergebnis wiederfinden.


            BTW: da ich diese Prepared Statements nicht mag, habe ich auch noch nie die Grenzen ausgelotet, also auch noch nie ausprobiert, was passiert, wenn die Ergebnismenge mehr Spalten enthält, als man anschlie0end mit bind anspricht. Gehen die restlichen einfach nur verloren?

            Grüße
            TS

            1. Hallo und guten Abend,

              Und dann werden diese Variablen bei jedem Fetch()-Durchlauf damit gefüllt und stehen sofort nach dem fetch() mit den neuen Werten (aktuelle Zeile der Ergebnismenge) zur Verfügung

              
                  $_monate = array();
              
                  while ($stmt->fetch())
                  {
                      $_monate[] = $monat;
                  } 
              
              

              Im Array $_monate sollte sich jetzt die Spalte monat aus dem Ergebnis wiederfinden.

              Ok, danke das habe ich jetzt soweit verstanden, das heißt also auch die Einträge werden automatisch mit einem , getrennt? Ich dachte immer diese muss ich von Hand irgendwie hinzufügen.


              BTW: da ich diese Prepared Statements nicht mag, habe ich auch noch nie die Grenzen ausgelotet, also auch noch nie ausprobiert, was passiert, wenn die Ergebnismenge mehr Spalten enthält, als man anschlie0end mit bind anspricht. Gehen die restlichen einfach nur verloren?

              Du meinst wenn in SELECT mehr drin steht als man anschließend im bind anspricht? Kann ich dir sagen, es knallt an allen Ecken :( Die Erfahrung musste ich heute Nachmittag schon machen.

              1. Hallo und guten Abend,

                Im Array $_monate sollte sich jetzt die Spalte monat aus dem Ergebnis wiederfinden.

                Ok, danke das habe ich jetzt soweit verstanden, das heißt also auch die Einträge werden automatisch mit einem , getrennt? Ich dachte immer diese muss ich von Hand irgendwie hinzufügen.

                Du erhältst in $_monate erst einmal ein PHP-Array mit einer "Spalte". Wenn Du das dann serialisieren willst als String array(1,7,12), dann muss Du den erst wieder zusammenbauen:

                $monate_arrstr = 'array(' . implode(',', $_monate) . ')';
                

                Wenn Du aber nur das Wertearray übergeben musst, dann steht das ja fertig für PHP aufbereitet in $_monate und du könntest das dann einfach per Zuweisung übertragen (PHP-intern).

                Leider weiß ich jetzt nicht, was Du brauchst und ob 'das andere Skript' auch ein PHP-Script ist.

                Grüße
                TS

                1. Hallo und guten Abend,

                  Du erhältst in *$_monate * erst einmal ein PHP-Array mit einer "Spalte". Wenn Du das dann serialisieren willst als String array(1,7,12), dann muss Du den erst wieder zusammenbauen:

                  $monate_arrstr = 'array(' . implode(',', $_monate) . ')';
                  

                  vielen vielen Dank, das war genau das was ich den ganzen Tag gesucht habe. Jetzt kann ich die Werte an ein weiteres Script übergeben.

            2. Tach!

              BTW: da ich diese Prepared Statements nicht mag, habe ich auch noch nie die Grenzen ausgelotet, also auch noch nie ausprobiert, was passiert, wenn die Ergebnismenge mehr Spalten enthält, als man anschlie0end mit bind anspricht. Gehen die restlichen einfach nur verloren?

              Das wär doch mal eine gute Gelegenheit, sie kennenzulernen. Und dann schau dir auch gleich noch PDO an, und du wirst feststellen, dass MySQLi den Anwender bei prepared Statements ziemlich einschränkt. Mann mus zwingend die Ergebnisspalten an Variablen binden und in sie hineinfetchen. PDO kann stattdessen auch nach einem PS herkömmlich fetchen, also beispielsweise pro Ergebniszeile ein Array oder Objekt liefern oder mit fetchAll() ein Array of Arrays.

              dedlfix.

          2. Tach!

            Jetzt bleibt noch die letzte Frage, wie ich $UserMonatArray[] = $Monat in $monate = array(3,5,7); bekomme, also die Zahlen sollen dynamisch gefüllt werden.

            Du hast das bereits so.

            [...] allerdings egal was ich mache ich bekomme die , nicht zwischen die Zahlen.

            Oh oh, da fehlen aber ganz gewaltig ein paar Programmiergrundlagen.

            $x = array(1, 2, 3);
            

            array(1, 2, 3) ist ein Array-Literal. Ein Literal ist das was man in den Code schreiben muss, um ein bestimmtes Ding zu bekommen. "foo" ist ein String-Literal. 42 ist ein Integer-Literal. Und so weiter und so fort. $a = "foo"; ist eine Anweisung, um die Variable $a mit der Zeichenfolge foo zu belegen. Literale sind festgelegte Schreibweisen für Werte, damit der Parser die verschiedene Dinge die er so in einem Code trifft auseinanderhalten kann.

            Die Funktion var_dump() zeigt den Inhalt einer Variable an. Die Ausgabe sieht allerdings ganz und gar nicht wie ein Literal aus. Da sind noch ein paar mehr Informationen drin, die man als PHP-Programmierer gut gebrauchen kann, beispielsweise Typ und Länge. Wenn du eine Literal-Schreibweise haben möchtest, dann musst du var_export() nehmen.

            Beim Literal array(1, 2, 3) sind keine Schlüsselwerte angegben, die legt PHP selbst fest. var_dump(array(1, 2, 3)) zeigt die jedoch mit an. Wenn du also eine solche Ausgabe hast:

            array(3) {
              [0]=>
              string(1) "3"
              [1]=>
              string(1) "5"
              [2]=>
              string(1) "7"
            }
            

            dann ist das zugehörige Literal: array("3", "5", "7"). In dem Fall sind die Werte Strings, in meinen Beispielen waren es Zahlen und die Ausgabe sähe so aus:

            array(3) {
              [0]=>
              int(1)
              [1]=>
              int(2)
              [2]=>
              int(3)
            }
            

            (Die Zahlen in Klammern nach dem int sind diesmal keine Längenangabe sondern die Zahlen selbst.)

            Wenn ich es richtig verstanden habe, muss ich zuerst ein leeres Array anlegen mit
            $Monate[] = "";

            Das hast du nicht richtig verstanden. Das Literal für ein leeres Array ist array() oder in aktuellen PHP-Versionen auch [], wenn es allein steht und nicht hinter einer Variablen.

            $Monate = array();
            $Monate = [];
            

            So werden leere Arrays angelegt und einer Variablen zugewiesen. Beide Zeilen sind gleichbedeutend. Deine Anweisung hat auch ein Array angelegt, aber das passiert nur, wenn $Monate vorher noch nicht als Variable vorhanden war. Dann passiert das Anlegen bei einer Zuweisung nebenbei mit. Dein Array ist außerdem nicht leer sondern mit einem Leerstring als dem ersten Wert angelegt worden. In ordentlich geschrieben entspricht das einem $Monate = array(""); oder auch deutlicher $Monate = array(0 => "");

            Dann dachte ich muss es so füllen: array_push($Monate, $UserMonatArray[]);

            Man kann array_push() nehmen, aber das ist umständlich zu notieren. Hier hast du aber einen Syntaxfehler. Wenn $variable[] links von einem = steht, dann soll dem Array in der Variable $variable ein Element zugewiesen werden. In allen anderen Fällen ist $variable[] ein lesender Zugriff, und dabei muss zwischen die beiden []-Klammern der Wert eines Schlüssels eingefügt sein, den man auszulesen gedenkt.

            Wie fügt man nun Werte zu einem Array in einer Variable hinzu? Nachfolgend die beiden Varianten:

            $variable[] = "wert";
            array_push($variable, "wert");
            

            dedlfix.