Jörg: Begrenzung bei Arraygröße in Formularen?

Hallo Forum,

ich habe gerade ein seltsames Verhalten festgestellt.

Ich erzeuge ein HTML-Formular, in dem ich über "post" einige Arrays dynamisch erzeuge und diese weiter gebe.

Der Inhalt des Formulars ist eine Tabelle, in dem Produkte stehen, die in verschiedenen Spalten geändert werden können.

Um dann die Änderungen nach Formularabsendung in der Datenbank updaten zu können, bilde ich per hidden-input diese Arrays mit den entsprechenden Inhalten.

Aber die Arrays brechen lokal bei 125 Einträgen ab, obwohl die Tabelle knapp 300 Einträge hat. Auf dem Produktivserver brechen sie bei 111 Einträgen ab. Beides reproduzierbar.

Daher meine Frage: Gibt es da irgendeine Beschränkung, die ich nicht kenne oder warum werden nicht alle 300 Einträge ins Array übernommen?

Jörg

akzeptierte Antworten

  1. Hallo Jörg,

    Ich erzeuge ein HTML-Formular, in dem ich über "post" einige Arrays dynamisch erzeuge und diese weiter gebe.

    was heißt das genau? Ich verstehe nicht wirklich, was du meinst.

    Der Inhalt des Formulars ist eine Tabelle, in dem Produkte stehen, die in verschiedenen Spalten geändert werden können.

    Um dann die Änderungen nach Formularabsendung in der Datenbank updaten zu können, bilde ich per hidden-input diese Arrays mit den entsprechenden Inhalten.

    Auch diese Beschreibung ist mir unklar.

    Aber die Arrays brechen lokal bei 125 Einträgen ab, obwohl die Tabelle knapp 300 Einträge hat. Auf dem Produktivserver brechen sie bei 111 Einträgen ab. Beides reproduzierbar.

    Daher meine Frage: Gibt es da irgendeine Beschränkung, die ich nicht kenne oder warum werden nicht alle 300 Einträge ins Array übernommen?

    Bei GET gibt es wohl eine Beschränkung der Länge - nicht durch die Spezifikation, aber durch die Implementierung. Der apache als vermutlich meistverwendeter Webserver akzeptiert meines Wissen maximal 16kB als Request URI.

    Bei POST gibt es diese Beschränkung meines Wissens nicht.

    Haben denn alle deine Parameter eindeutige Namen? Denn wenn ein Parametername mehrmals in den GET- oder POST-Daten vorkommt, "gewinnt" der letzte Wert, und die vorher genannten sind für PHP verloren.

    Ansonsten kann ich nur Nummer 5 zitieren: Mehr Input!

    Einen schönen Tag noch
     Martin

    --
    Es liegt allein an uns, ob wir aus den vielen Steinen, die wir einander in den Weg legen, Mauern oder Brücken bauen. (Ernst Ferstl)
    1. Hallo Martin,

      ok, dann versuch ichs mal mit etwas Quasi-Code.

      print_r($_POST['array1'])
      
      DB-Abfrage
      Formular action=post
      while (DB-Ergebnismenge) {   // Ergebnismenge hat 300 Einträge
      hidden input name=array1[] value = row[0]
      hidden input name= array2[] value = row[n]
      }
      submit zu sich selbst
      

      Ergibt in der Ausgabe:

      [array1] => Array
              (
                  [0] => 99330
                  [1] => 152224
                  ... 
                  [124] => 189112
                  [125] => 189113
              )
      

      Ist das (ggf. zusammen mit meinem Eingagspost) verständlicher?
      Warum ist bei Eintrag 125 Schluss, obwohl laut Script und auch laut Quelltext ein array1 mit 300 Einträgen gebildet wird?

      Jörg

      1. Hi,

        hatte mal ein ähnliches Problem. Damals für einen php Import. Hat sich rausgestellt, dass ich zuviele Werte über Formularelemente transportiert habe.
        "post_max_size".

        1. Hi,

          hatte mal ein ähnliches Problem. Damals für einen php Import. Hat sich rausgestellt, dass ich zuviele Werte über Formularelemente transportiert habe.
          "post_max_size".

          Hallo, ja, anscheinend ist das was dran. Habe das jetzt umprogrammiert und für jede zeile einen Einzelupdate spendiert. Das Gesamtpaket biete ich nur noch bei weniger als 75 Zeilen an (inkl. Arraybildung) und jetzt läufts prima.

          Das Problem war zuvor, dass z.b. Zeile 250 auch als Einzelupdate dieser Zeile nicht funktioniert hat, wenn ich die großen Arrays weiter gebe.

          Wundert mich zwar, dass 4 eindimensionale Arrays a 300 Einträge mit max. 25 Zeichen hier php überfordern, aber scheint so zu sein.

          Danke für den Hinweis,

          Jörg

        2. Hi,

          hatte mal ein ähnliches Problem. Damals für einen php Import. Hat sich rausgestellt, dass ich zuviele Werte über Formularelemente transportiert habe.
          "post_max_size".

          Das hätte folgendes Resultat:

          Warning: Unknown: POST Content-Length of 18828889 bytes exceeds the limit of 8388608 bytes in Unknown on line 0

          Warning: Cannot modify header information - headers already sent in Unknown on line 0

          und $_POST würde gar nicht erst aus dem übergebenem Input ermittelt („line 0“ meint vor Abarbeitung des Skriptes), wäre also leer.

      2. obwohl laut Script und auch laut Quelltext ein array1 mit 300 Einträgen gebildet wird?

        Glaub ich nicht. Lass Dir den tatsächlich abgesendeten SQL-Request anzeigen und führe den manuell in der Datenbank aus.

        1. Bei mir kommen nach diesem Schnelltest …
        <?php
        if ( empty( $_POST['data'] ) ) {
        ?>
        <html>
        <form method="post">
        <?php
        for ($i=0; $i<300; $i++) {
        	echo '<input type="hidden" name="data[]" value="' . 'Ha Nr:' .$i.   '">';
        }
        echo '<button>Klick</button>';
        ?>
        <html>
        <?php } else {
        	header ( 'Content-Type:text/plain; charset=utf-8' );
        	print_r( $_POST['data'] );
        }
        

        wie erwartet auch 300 Werte in $_POST['data'] an.

        Zeige also verifizierbar was Du gemacht hast. Vielleicht findest Du ja schon dabei Deinen Fehler.

        1. Zeige also verifizierbar was Du gemacht hast. Vielleicht findest Du ja schon dabei Deinen Fehler.

          Versuchen wirs:

          DB-Abfrage manuell in php-myAdmin ergibt:

          Zeige Datensätze 0 - 231 (232 insgesamt, Die Abfrage dauerte 0,2002 Sekunden.)

          <FORM ACTION="/myscript.php?aktion=artikelupdate METHOD="POST">
          
          	echo("
          	<INPUT TYPE=HIDDEN NAME=arr_alle[] VALUE=\"$row_u[9]\">
          	<INPUT TYPE=HIDDEN NAME=\"alte_art_nr[".$row_u[9]."]\" VALUE=\"$row_u[6]\">
          	<INPUT TYPE=HIDDEN NAME=\"alte_lief_id[".$row_u[9]."]\" VALUE=\"$row_u[20]\">
          	<INPUT TYPE=HIDDEN NAME=t_nummer[".$row_u[9]."] VALUE=\"$row_u[9]\">	
          	");
          
          // ...
          
          	
          	echo("
          	<INPUT TYPE=TEXT Name=\"einzel_art_nr[".$row_u[9]."]\" SIZE=10 MAXLENGTH=30 VALUE=\"$row_u[6]\"></TD>
          	<TD><INPUT TYPE=TEXT Name=\"einzel_art_bez[".$row_u[9]."]\" SIZE=20 MAXLENGTH=50 VALUE=\"$row_u[7]\"></TD>
          	<TD><INPUT TYPE=TEXT Name=\"einzel_art_ek[".$row_u[9]."]\" SIZE=5 MAXLENGTH=50 VALUE=\"$row_u[15]\"\"></TD>
          	<TD><INPUT TYPE=TEXT Name=\"einzel_art_vk[".$row_u[9]."]\" SIZE=5 MAXLENGTH=50 VALUE=\"$row_u[16]\"\"></TD>
          	");
          

          HTML-Quelltext (Kontrolle, ob alle Arrays gebildet werden) Hier bei Artikelpos. 232

          
          	<INPUT TYPE=HIDDEN NAME=arr_alle[] VALUE="193289">
          	<INPUT TYPE=HIDDEN NAME="alte_art_nr[193289]" VALUE="24.0201P">
          	<INPUT TYPE=HIDDEN NAME="alte_lief_id[193289]" VALUE="3882">
          	<INPUT TYPE=HIDDEN NAME=t_nummer[193289] VALUE="193289">	
          	
          usw.
          

          Dann nach dem Absenden das Ergebis von print_r($_POST):

          Array
          (
              [aktion] => artikelupdate
              [arr_alle] => Array
                  (
                      [0] => 99950
                      [1] => 151924
          	    ...
                      [124] => 189612
                      [125] => 189613
                  )
          
              [alte_art_nr] => Array
                  (
                      [99950] => B222100.01.202
                      [151924] => 24.04.2111P
          	     ...
                      [189611] => 36.00.166P
                      [189612] => 36.00.534S
                  )
          
              [alte_lief_id] => Array
                  (
                      [99950] => 3882
                      [151924] => 3882
          	    ...
                      [189611] => 3882
                      [189612] => 3882
                  )
          
              [t_nummer] => Array
                  (
                      [99950] => 99950
                      [151924] => 151924
          	     ...
                      [189611] => 189611
                      [189612] => 189612
                  )
          
              [einzel_art_nr] => Array
                  (
                      [99950] => B332100.01.202
                      [151924] => 24.11.244P
          	    ...
                      [189611] => 36.00.166P
                      [189612] => 36.00.534S
                  )
          
              [einzel_art_bez] => Array
                  (
                      [99950] => Tsetgerä Typ: 201 - Elektro
                      [151924] => Türverschluß
          	    ...
                      [189611] => Druckschlauch f. Reinigung
                      [189612] => Pflegemittelschlauch
                  )
          
              [einzel_art_ek] => Array
                  (
                      [99950] => 10973.60
                      [151924] => 1.00
                      ...
                      [189611] => 4.50
                      [189612] => 9.70
                  )
          
              [einzel_art_vk] => Array
                  (
                      [99950] => 12510.36
                      [151924] => 0.00
          	    ...
                      [189611] => 8.10
                      [189612] => 17.46
                  )
          
          )
          

          (Bitte nicht auf Art.Nr. und Bezeichnungen achten, weil ich die wild geändert habe, damit man keine Rückschlüsse auf echte Lieferanten und/oder EKs ziehen kann. Entscheidend ist, dass nur 125 Arrayeinträge in den jeweiligen Arrays vorhanden sind, aber 232 abgesendet wurden)

          Jörg

  2. Um dann die Änderungen nach Formularabsendung in der Datenbank updaten zu können, bilde ich per hidden-input diese Arrays mit den entsprechenden Inhalten.

    Mal was ganz anderes:

    • Wie bedienbar ist das denn?
    • Schon mein Test nur mit 1. Formular bauen und 2. zurücksenden, 3. $_POST mit print_r() anzeigen war auf dem Localhost(sic!) „arschlangsam“.
    • Du willst nicht ernsthaft solche Datenmengen aus der Datenbank holen, aufbereiten, zum Browser senden, dann von diesem zum Server senden, wieder aufbereiten und zur Datenbank schaufeln um den Datenbankserver dann herausfinden zu lassen, was geändert wurde - oder? (was würdest Du sagen, wenn Du auf dem Fischmarkt statt des Herings die ganze Ostsee eingepackt bekommst?)

    Das sieht gleich unter mehrfachen Aspekten danach aus, als bräuchtest Du eine andere Vorgehensweise.

    1. Mal was ganz anderes:

      • Wie bedienbar ist das denn?
      • Schon mein Test nur mit 1. Formular bauen und 2. zurücksenden, 3. $_POST mit print_r() anzeigen war auf dem Localhost(sic!) „arschlangsam“.

      Nö, das geht ansich recht flott.
      Aber Du hast recht, dass ich gleich mehrere Selektionskriterien eingerichtet habe, um die Artikellisten möglichst klein zu bekommen.
      In der Praxis stehen nunmehr max. 10-15 Einträge auf einem Listenblatt.

      • Du willst nicht ernsthaft solche Datenmengen aus der Datenbank holen, aufbereiten, zum Browser senden, dann von diesem zum Server senden, wieder aufbereiten und zur Datenbank schaufeln um den Datenbankserver dann herausfinden zu lassen, was geändert wurde - oder?

      Nein, ich sag ja.
      10-15 Einträge sind praxisrelevant.
      Sollten mehr als 50 Einträge vorhanden sein, muss der User über Einzelupdate der Zeile gehen.

      Jörg

  3. Moin,

    Daher meine Frage: Gibt es da irgendeine Beschränkung, die ich nicht kenne […]

    Ja, max_input_vars – allerdings ist der Standardwert für die Einstellung 1000. Oder hast du 8 Werte pro Zeile und übertragen werden nur 125 Zeilen (statt 300)?

    Gruß
    Tobias

    1. Jepp. Das ist es. Und das bricht auch bei

      ini_get('max_input_vars');
      

      ab. (Sagt das Handbuch und mein Test.)

      Das hier steht im error-Log:

      Warning: Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0

      @Jörg: Dein tatsächlicher Fehler ist also, dass Du nicht ins Logfile schaust und mit schlechten Einstellungen für das Logging und die Anzeige von Fehlern testest.

      1. @Jörg: Dein tatsächlicher Fehler ist also, dass Du nicht ins Logfile schaust und mit schlechten Einstellungen für das Logging und die Anzeige von Fehlern testest.

        Ok.
        Danke für die schnelle Hilfe.

        Jörg

    2. Hallo,

      Ja, max_input_vars – allerdings ist der Standardwert für die Einstellung 1000. Oder hast du 8 Werte pro Zeile und übertragen werden nur 125 Zeilen (statt 300)?

      Ja, das dürfte hin kommen.
      ich erzeuge je Zeile 8 Arrays mit je einem Wert.

      Danke für die Hilfe.

      Jörg