wucher wichtel: Zugriff auf variable Anzahl von Checkboxen

Hallo!

Also, ich habe ein kleines Problem. Und zwar habe ich einen Blog programmiert. Der Admin soll die Möglichkeit haben, unerwünschte Kommentare zu löschen. Dazu gebe ich mit PHP eine Tabelle aus, in der Infos zu allen Kommentaren stehen. Am Anfang jeder Zeile ist eine Checkbox. Wenn diese gewählt ist, dann soll dieser Kommentar gelöscht werden.

Wenn ich wüsste, dass es insgesamt x Kommentare gibt (also x Checkboxen), dann könnte ich problemlos die Werte per $_POST['checkboxXY'] abfragen. Aber genau das weiss ich eben nicht. Wie kann ich also unabhänig wieviele Checkboxen es sind, abfragen, ob für diese ein Wert übergeben wurde, oder nicht?

Geht das ganze auch eleganter? Ankommen tut bei mir:

Array ( [comment2] => 2 [comment3] => 3 )

Eigentlich brauche ich gar nicht die Namen der Checkboxen wissen, sondern nur hier z.B. die Werte 2 und 3. Dann könnte ich die Kommentare löschen, die die ID 2 oder 3 haben. Kann ich also irgendwie nur die Werte ohne die Namen der Boxen abfragen?

Oder gibt es eine Lösung, die ich gar nicht sehe?

Vielen Dank für eure Tips und Hilfe!

ciao, ww

--
Ein japanisch-deutsches Gedicht
sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
  1. echo $begrüßung;

    Wenn ich wüsste, dass es insgesamt x Kommentare gibt (also x Checkboxen), dann könnte ich problemlos die Werte per $_POST['checkboxXY'] abfragen. Aber genau das weiss ich eben nicht. Wie kann ich also unabhänig wieviele Checkboxen es sind, abfragen, ob für diese ein Wert übergeben wurde, oder nicht?

    Wenn in den Namen der Elemente eckige Klammern vorkommen, dann interpretiert PHP diese ähnlich wie beim Anlegen eines Arrays. Bei name[] wird das Array name um ein Element erweitert, wobei der Schlüssel automatisch hochgezählt wird (name ist ein Array im $_POST oder $_GET-Array. Ein <input name="name[]" value="value"> entspricht also: $_POST['name'][] = 'value';). Mit name[x] ist der x der Schlüssel (also $_POST['name']['x'] = 'value';).

    Um durch ein Array mit unbekannten Schlüsselwerte zu laufen nimmt man foreach ($array as $key => $value)

    echo "$verabschiedung $name";

    1. Hallo!

      Ok. Danke euch beiden. Ich versuche mich gerade an der Lösung von dedlfix. Ich lese jetzt erstmal die wichtigen Stellen im Manual und versuch es dann. Vielleicht komme ich später nochmal, weil etwas nicht klappt :) Vielen Dank nochmal!

      ciao, ww

      --
      Ein japanisch-deutsches Gedicht
      sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
    2. Hello,

      Um durch ein Array mit unbekannten Schlüsselwerte zu laufen nimmt man foreach ($array as $key => $value)

      Um es genau zu nehmen, sollten die Schlüsselwerte aber nicht unbekannt sein!
      Mein Beispiel nimmt allerdings auch keine Rücksicht darauf.

      Für eine Multiuser-Umgebung würde man so vorgehen, dass man eine Liste der zu löschenden Datensätze in der Session abspeichert. Die Liste hat zu enthalten

      - ID-list in der Liste
        - ID-data des Datensatzes in der Tabelle der DB
        - lastupdate letztes Veränderungsdatum des Datensatzes
        - angezeigter Wert in der Liste

      Wird nun der Löschauftrag gegeben z.B. mit dem Formular aus meinem Beispiel, dann muss man in der Löschfunktion prüfen

      Enthält die POST-Liste IDs, die nicht in der Session in ID-list vorhanden sind?
        --> sofort abrechen! Löschauftrag passt nicht zur letzten Anforderung

      alle anderen kann man dann mit der Schleife über $_POST['chk']['delete'] oder wie man das n
        Steuerelemet nennt abarbeiten und _jeden_einzel_ bei der DB zur Löschung anfordern

      DELETE from $tabelle where ID = $id-data and LASTUPDATE = $lastupdate

      Das verhindert, dass Datensätze gelöscht werden können, die zwischenzeitlich verändert wurden
      LASTUPDATEsollte die erste Timestamp-Spalte in der MySQL-Tabelle sein, damit sie bei jeder Veränderung automatisch geführt wird. Bei anderen DBMS muss man vergleichbare Maßnahmen treffen

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

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

      1. Hallo!

        Oh man :) Ich muss noch dermaßen viel lernen... :( Das einzige was mich tröstet ist, dass ich mit HTML, CSS und JS auch so angefangen habe, wie jetzt mit PHP ;-)

        ciao, ww

        --
        Ein japanisch-deutsches Gedicht
        sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
      2. echo $begrüßung;

        Um durch ein Array mit unbekannten Schlüsselwerte zu laufen nimmt man foreach ($array as $key => $value)

        Um es genau zu nehmen, sollten die Schlüsselwerte aber nicht unbekannt sein!

        Bei meinen Ausführungen hatte ich erst

        <input type="checkbox" name="todelete[1]">  
        <input type="checkbox" name="todelete[2]">  
        <input type="checkbox" name="todelete[3]">
        

        im Sinn, so dass sich bei angehakter zweiten und dritte Box die Schlüssel 2 und 3 im $_POST['todelete']-Array befinden. (Alternativ als mit foreach diese Schlüssel zu ermitteln gäbe es auch noch array_keys().)

        Doch es gibt auch noch eine andere Methode, die mir besser erscheint.

        <input type="checkbox" name="todelete[]" value="1">  
        <input type="checkbox" name="todelete[]" value="2">  
        <input type="checkbox" name="todelete[]" value="3">
        

        So hat man die zu löschenden IDs gleich als Array vorliegen und kann sie direkt implodieren.
        sprintf('... WHERE id IN (%s)', implode(',', $_POST['todelete']))
        Vorher muss man natürlich noch sicherstellen, dass die Werte auch Zahlen sind, um sich keine SQL-Injection einzufangen. Also kann man sich das Durchlaufen doch nicht ganz ersparen.

        echo "$verabschiedung $name";

        1. Hallo!

          <input type="checkbox" name="todelete[]" value="1">

          <input type="checkbox" name="todelete[]" value="2">
          <input type="checkbox" name="todelete[]" value="3">

            
          Genau so habe ich es auch.  
            
          
          > Vorher muss man natürlich noch sicherstellen, dass die Werte auch Zahlen sind, um sich keine SQL-Injection einzufangen. Also kann man sich das Durchlaufen doch nicht ganz ersparen.  
            
          Wie kann ich überprüfen, ob die Werte Zahlen sind? Wie meinst du das mit Durchlaufen?  
            
          ciao, ww
          
          -- 
          [Ein japanisch-deutsches Gedicht](http://www.aiki-sphere.de/goethe.html)  
            
          sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
          
          1. echo $begrüßung;

            Wie kann ich überprüfen, ob die Werte Zahlen sind? Wie meinst du das mit Durchlaufen?

            Zum Prüfen auf Zahlen gibt es einige Funktionen:

            Vorab: Alle Werte im $_POST- und $_GET-Array sind vom Typ String[*].

            • is_numeric()
              Prüft ob der Inhalt irgendwie nach Zahl aussieht. Erkennt auch Zahlen mit Dezimalpunkt, Exponential- und Hex-Darstellung als gültig an, und das will man oftmals nicht.

            • is_int()
              Prüft ob der Typ einer Variablen Integer ist. Strings sind keine Integer-Typen, man benötigt einen Typecast, und dann braucht man auch is_int() nicht mehr, weil der Typecast garantiert den Ziel-Typ zurückliefert.

            • ctype_digit()
              Die ctype-Funktionen sind gelegentlich nicht installiert. Vor Verwendung phpinfo() befragen.

            • intval()
              Macht aus dem übergebenen Wert garantiert einen Integer. Zur Not erhält man 0.

            Und dann gibt es noch die Filter Functions. Die benötigen aber eine recht aktuelle Installation. (Und uneingeschränkt empfehlenswert sind sie leider vom Ansatz her nicht. Siehe letzter Abschnitt: http://www.php-security.org/MOPB/PMOPB-45-2007.html)

            Diese Funktionen musst du nun über deine Werte laufenlassen. Nein, nicht alle auf einmal. Such dir diejenige aus, die dir am geeignetsten erscheint.

            Ein intval() macht ungültige Werte unschädlich, IDs mit dem Wert 0 sollte es nicht geben, für übergebene ungültige Werte wird also kein unschuldiger Datensatz gelöscht. Das ist eine stillschweigende Methode, ungültige Werte zu ignorieren.
            Auf ein negatives Ergebnis der Prüf-Funktionen kannst du auch aktiv reagieren und z.B. den Vorgang wegen Angriffsverdacht abbrechen.

            [*] Die Ausnahme Array erwähne ich mal nicht, das verwirrt sonst noch. :-)

            echo "$verabschiedung $name";

            1. Hallo!

              Wow. Danke für die genauen Ausführungen. Vielen vielen Dank!

              ciao, ww

              --
              Ein japanisch-deutsches Gedicht
              sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
    3. Hallo!

      Also ich habe mir jetzt bei php.net das Beispiel zu foreach angeschaut. Hier meine Fragen:

      Warum braucht man diese Schreibweise:
      foreach (array_expression as $key => $value) Anweisung und benützt nicht einfach foreach (array_expression as $value) Anweisung?

      Was bedeutet die Schreibweise =>?

      Was muss ich mit dem POST-Array machen, dass ich dessen Werte in einer foreach-Schleife abarbeiten kann? Bei den Beispielen auf php.net steht immer nur ein "normaler" Array.

      Vielen Dank für eure Erklärungen und Hilfe!

      ciao, ww

      --
      Ein japanisch-deutsches Gedicht
      sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
      1. hi,

        Also ich habe mir jetzt bei php.net das Beispiel zu foreach angeschaut. Hier meine Fragen:

        Warum braucht man diese Schreibweise:
        foreach (array_expression as $key => $value) Anweisung und benützt nicht einfach foreach (array_expression as $value) Anweisung?

        Was bedeutet die Schreibweise =>?

        Das, was auf der von dir selbst gerade noch verlinkten Seite steht:

        "Die zweite Form arbeitet genauso, außer dass bei jedem Durchlauf auch der aktuelle Schlüssel der Variablen $key zugewiesen wird."

        Was muss ich mit dem POST-Array machen, dass ich dessen Werte in einer foreach-Schleife abarbeiten kann? Bei den Beispielen auf php.net steht immer nur ein "normaler" Array.

        $_POST ist ein "normales" Array.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hallo!

          Ich habe jetzt versucht, mir die Werte von $_POST so ausgeben zu lassen:

            
          foreach($_POST as $key => $value){  
            echo 'Wert: '.$value.'<br>';  
          }  
          
          

          Ausgegeben wird: Wert: Array

          Wie muss ich es richtig schreiben?

          Ich kann erst etwas später wieder Fragen stellen. Also bitte den Thread nicht aus den Augen verlieren :-)

          ciao, ww

          --
          Ein japanisch-deutsches Gedicht
          sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
          1. hi,

            Ich habe jetzt versucht, mir die Werte von $_POST so ausgeben zu lassen:

            foreach($_POST as $key => $value){
              echo 'Wert: '.$value.'<br>';
            }

            
            > Ausgegeben wird: Wert: Array  
              
            Also ist das Element, dessen Wert du dort auszugeben versuchst, seinerseits wiederum ein Array. Das lässt sich natürlich nicht mit echo ausgeben, da kommt dann nur die Ausgabe 'Array' bei heraus.  
              
            
            > Wie muss ich es richtig schreiben?  
              
            Wenn das Element seinerseits wiederum ein Array ist, möchte es natürlich auch wieder durchlaufen werden. Mit is\_array könntest du das erst mal überprüfen. In fortgeschrittenem Stadium käme dann noch Rekursion hübsch passend dazu, das dürfte aber erst mal nicht erforderlich sein.  
              
            Und statt einem echo könntest du natürlich auch erst mal print\_r oder var\_dump nutzen, wenn du dir erst mal lediglich über die Struktur der Daten klar(er) werden möchtest.  
              
            gruß,  
            wahsaga  
              
            
            -- 
            /voodoo.css:  
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            
            1. Hallo!

              Danke! Ich habe es jetzt durch Verschachteln von foreach-Schleifen geschafft. Dadurch bekomme ich jetzt die Werte. Ist das schon der richtige Weg?

                
              foreach($_POST as $key => $value){  
                if(is_array($value)) {  
                  foreach($value as $newKey => $newValue){  
                    echo 'Wert: '.$newValue.'<br>';  
                  }  
                } else {  
                  echo "Fehler!";  
                }  
              }  
              
              

              Auf jeden Fall klappt es. Danke dafür!

              ciao, ww

              --
              Ein japanisch-deutsches Gedicht
              sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
              1. echo $begrüßung;

                Danke! Ich habe es jetzt durch Verschachteln von foreach-Schleifen geschafft. Dadurch bekomme ich jetzt die Werte. Ist das schon der richtige Weg?

                Kommt drauf an. Du musst natürlich nicht das komplette $_POST-Array durchlaufen, wenn du schon weißt, auf welche Werte du zugreifen möchtest. Wenn also deine Zu-Löschen-Checkboxen alle "delete[]" heißen, kannst du dem foreach auch direkt das Array $_POST['delete'] übergeben und musst dich nicht schrittweise durch das $_POST durchhangeln.

                echo "$verabschiedung $name";

                1. Hallo!

                  Wenn also deine Zu-Löschen-Checkboxen alle "delete[]" heißen, kannst du dem foreach auch direkt das Array $_POST['delete'] übergeben und musst dich nicht schrittweise durch das $_POST durchhangeln.

                  Ok, danke schön! Das wusste ich nicht.

                  ciao, ww

                  --
                  Ein japanisch-deutsches Gedicht
                  sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
  2. Hi wichtel,

    Oder gibt es eine Lösung, die ich gar nicht sehe?

    Du kannst z.B. den Checkboxen Namen geben, die du dann numerisch auswerten kannst check<eindeutigeNummer>[1] etc. Dann prüfst du auf Vorhandensein (wenn nicht aktiviert, wird es ja auch nicht übergeben) mit foreach und löschst danach.

    ciao
    romy

    [1] sinnvollerweise die ID aus der Datenbanktabelle, da du die Checkboxen ja wahrscheinlich generierst aus der Datenbank ;))

  3. Hello,

    $GLOBALS['bgcolor'][0] = '';
    $GLOBALS['bgcolor'][1] = ' even';    ## --> als CSS-Klasse anlegen
    $GLOBALS['bgcolor'][2] = ' odd';     ## --> als CSS-Klasse anlegen

    function make_out_table($_data='')
    {
      if(!is_array($_data)) return false;

    $out = '';
      $out .= "  <table>\n";

    $line = 0;

    foreach($_data as $key => $val)
      {
        $class = "trow ".$GLOBAL['_bgcolor'][($key % 2) + 1];
        $val = htmlentities($val,ENT_QUOTES);

    $out .= "    <tr class="$class">\n";
        $out .= "       <td class="col01">$key</td>\n";
        $out .= "       <td class="col02">$val</td>\n";
        $out .= "       <td class="col03">".
                            "<input type="checkbox" class="delete" ".
                            "id="chk$key" name="chk[$key]" value="$val">\n";
        $out .= "    </tr>\n";
      }

    $out .= "  </table>\n";

    return $out;
    }

    $_data ist ein Datenarray
    Pack das Ergebnis mal in ein FORM und schau dir die Post-Vars an

    function delete_entries(&$_data,$del_btn_name)
    {
      $delete = 0;   ## Löschzähler

    if (!isset($_POST[$del_btn_name]) or !is_array($_POST[$del_btn_name]))
      {
        $out' = "<p class="error">Bitte erst Löschmarkierung setzen</p>\n";
      }
      else
      {
        foreach($_POST[$del_btn_name] as $key => $val)
        {
          if (isset($_data[$key]) and $_data[$key] == $val)
          {
            unset($_data[$key]);
            $delete++;
          }
          else
          {
            $out .= "<p class="message">Datensatz Nr. $key konnte nicht gelöscht werden</p>\n";
          }
        }
      }
      $out .= "<p class="warning">$delete Sätze zur L&ouml;schung markiert, <br> jetzt ausführen?</p>";

    return $out;
    }

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

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

    1. Hallo!

      Danke für das Script. Aber das Problem ist, dass ich nicht so richtig verstehe, was alles passiert und warum. Und ich mache das ganze Projekt um PHP zu lernen. Ich probiere jetzt mal selber, das ganze zu lösen und versuche das ganze so gut hinzubekommen, wie du es hier gepostet hast. Ich glaube, dass ich dann ziemlich viel gelernt habe. Vielen Dank!

      ciao, ww

      --
      Ein japanisch-deutsches Gedicht
      sh:(  fo:|  ch:~  rl:(  br:>  n4:~  ie:%  mo:)  va:)  de:]  zu:)  fl:(  ss:|  ls:~  js:)
    2. Hello,

      hab nun ein Beispiel unter

      http://selfhtml.bitworks.de/strukturierung/deleteliste.php

      ins Netz gestellt.

      Der gepostete Code hatte zuviele Fehler :-((
      Musste eben zu schnell gehen.

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

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau