burnhard1979: aktivierte checkboxen abfrage

Hallo liebe Leser,

ich habe hier ein kleines Problem und irgendwie finde ich nichts in google noch fällt mir eine richtig gute Lösung ein:

es geht um folgendes...ich habe eine Datenbank. in dieser Datenbank werden relevante Daten zu einem gewissen Produkt gespeichert.

nun habe ich ein Formular mit n-checkboxen die die Geräte darstellen. zb. ger1, ger2, ger3 etc zudem gibts noch Gruppen, denen bestimmte Geräte zugewiesen sind.

die Checkboxen werden mittels 0 und 1 in einer mysql Datenbank gespeichert.

jetzt habe ich aber das Problem - wenn ich genau von ger1 und ger23 alle Einträge haben will...wie übergebe ich das in ein sql Statement...mittels php ermittle ich den wert der Checkboxen (sprich 1 und 0) und schicke sie dann meinem Statement...
also im Prinzip müsste es so heissen:

select * from daten where ger1=$ger1 and ger2=$ger ... and ger52=$ger52

aber das ist natürlich falsch...nur wie kann ich sagen wir mal die Geräte, die nicht ausgewählt sind generell aus dem Statement löschen (sprich alle $xxx=0)???

wer kann mir da helfen? über einen Hinweis wäre ich sehr dankbar.

lg, bernhard

  1. Hallo liebe Leser,

    ich habe hier ein kleines Problem und irgendwie finde ich nichts in google noch fällt mir eine richtig gute Lösung ein:

    es geht um folgendes...ich habe eine Datenbank. in dieser Datenbank werden relevante Daten zu einem gewissen Produkt gespeichert.

    nun habe ich ein Formular mit n-checkboxen die die Geräte darstellen. zb. ger1, ger2, ger3 etc zudem gibts noch Gruppen, denen bestimmte Geräte zugewiesen sind.

    die Checkboxen werden mittels 0 und 1 in einer mysql Datenbank gespeichert.

    jetzt habe ich aber das Problem - wenn ich genau von ger1 und ger23 alle Einträge haben will...wie übergebe ich das in ein sql Statement...mittels php ermittle ich den wert der Checkboxen (sprich 1 und 0) und schicke sie dann meinem Statement...
    also im Prinzip müsste es so heissen:

    select * from daten where ger1=$ger1 and ger2=$ger ... and ger52=$ger52

    aber das ist natürlich falsch...nur wie kann ich sagen wir mal die Geräte, die nicht ausgewählt sind generell aus dem Statement löschen (sprich alle $xxx=0)???

    wer kann mir da helfen? über einen Hinweis wäre ich sehr dankbar.

    lg, bernhard

    Hallo Bernard,

    ich verstehe Dein Problem nicht ganz. Du hast also 52 Felder in der Datenbank, die jeweils 0 oder 1 enthalten, richtig? (Ob das ein sinnvolles Design der DB ist sei mal dahingestellt)
    und Du hast 52 Variablen $ger1 bis $ger52, die jeweils je nach angeklickter checkbox einen Wert von 0 oder 1 bekommen.
    Soweit richtig?

    select * from daten where ger1=$ger1 and ger2=$ger ... and ger52=$ger52

    aber das ist natürlich falsch...

    Wieso ist das "natürlich falsch"?

    Was genau willst Du tun? Alle Produkte anzeigen, die bei allen angeklickten Geräten (und nur bei diesen) eine 1 haben?
    Oder alle Produkte, die bei den angeklickten Geräten eine 1 haben, egal wie die anderen Checkboxen aussehen?
    Oder alle Produkte, die bei mindestens einem der angeklickten Geräte eine 1 haben?

    Viele Grüsse

    Matthias

    1. Hallo Bernard,

      ich verstehe Dein Problem nicht ganz. Du hast also 52 Felder in der Datenbank, die jeweils 0 oder 1 enthalten, richtig? (Ob das ein sinnvolles Design der DB ist sei mal dahingestellt)
      und Du hast 52 Variablen $ger1 bis $ger52, die jeweils je nach angeklickter checkbox einen Wert von 0 oder 1 bekommen.
      Soweit richtig?

      hallo matthias,
      zuerst mal danke für deinen kommentar - ja, das mit den variablen siehst du genau richtig. dass meine "datenbank" nicht das topmodell in design ist, ist mir auch klar. da ich aber kein "guru" in dieser sache bin habe bzw. musste ich es so lösen und es funktioniert eigentlich bis jetzt auch :-).

      select * from daten where ger1=$ger1 and ger2=$ger ... and ger52=$ger52

      aber das ist natürlich falsch...

      Wieso ist das "natürlich falsch"?

      Was genau willst Du tun? Alle Produkte anzeigen, die bei allen angeklickten Geräten (und nur bei diesen) eine 1 haben?
      Oder alle Produkte, die bei den angeklickten Geräten eine 1 haben, egal wie die anderen Checkboxen aussehen?
      Oder alle Produkte, die bei mindestens einem der angeklickten Geräte eine 1 haben?

      Viele Grüsse

      Matthias

      ja falsch ist es eigentlich nicht, nur bekomme ich dann natürlich nicht das ergebnis was ich will. was ich genau will - also wenn ich jetzt aus diesen 50 geräten 3 aussuche, will ich alle einträge haben, bei denen in der spalte "ger23" eine eins steht, in der spalte "ger45" und in der spalte "ger22" ebenfalls jeweils eine eins steht...das können unter umständen ja mehrere einträge sein.

      ich habe mir darüber schon gedanken gemacht. im prinzip sollte es eine dynamische sql abfrage sein so ala

      select * from datenbank where feld1 is not null (if ger1=1 then "and ger1=1 else "") etc etc...

      ich weiss nicht, ob ich das richtig erklären kann...wenn nicht bitte nochmal fragen!

      danke, lg bernhard

      1. Hello,

        ja falsch ist es eigentlich nicht, nur bekomme ich dann natürlich nicht das ergebnis was ich will. was ich genau will - also wenn ich jetzt aus diesen 50 geräten 3 aussuche, will ich alle einträge haben, bei denen in der spalte "ger23" eine eins steht, in der spalte "ger45" und in der spalte "ger22" ebenfalls jeweils eine eins steht...das können unter umständen ja mehrere einträge sein.

        ich habe mir darüber schon gedanken gemacht. im prinzip sollte es eine dynamische sql abfrage sein so ala

        select * from datenbank where feld1 is not null (if ger1=1 then "and ger1=1 else "") etc etc...

        $fieldlist = "id, geraetename, ansch\_datum";
          $table     = "daten";

        $where = "";
          if isset($POST['ger']) and is_array($POST['ger']))
          {
            foreach($POST['ger'] as $key => $val)
            {
              $where .= " and ger".intval($key)." = 1";
            }
          }

        $sql = "select $fieldlist from $table where true $where";

        echo $sql;   ### zur Kontrolle

        Das ist natürlich so nur verkürzt dargestellt, denn wenn man richtig mach  will, müsste man auch noch überprüfen, ob die Spalte, die man in der Foreach-Schleife baut, überhaupt im Satzformat der Tabelle vorhanden ist. Anderenfalls bestraft Dich spätestens die SQL-Abfage mit einem Fehler-Status und einer Meldung.

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

        Tom

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

        1. servus Tom,

          zuerst mal danke für deine Hilfe. wenn ich mir das so ansehe, vermute ich aber, dass ich die "Betitelung" der Checkboxen anders machen muss - oder können die trotzdem $ger1 bis $gern heissen?

          danke, lg bernhard

          Hello,

          $fieldlist = "id, geraetename, ansch\_datum";
            $table     = "daten";

          $where = "";
            if isset($POST['ger']) and is_array($POST['ger']))
            {
              foreach($POST['ger'] as $key => $val)
              {
                $where .= " and ger".intval($key)." = 1";
              }
            }

          $sql = "select $fieldlist from $table where true $where";

          echo $sql;   ### zur Kontrolle

          Das ist natürlich so nur verkürzt dargestellt, denn wenn man richtig mach  will, müsste man auch noch überprüfen, ob die Spalte, die man in der Foreach-Schleife baut, überhaupt im Satzformat der Tabelle vorhanden ist. Anderenfalls bestraft Dich spätestens die SQL-Abfage mit einem Fehler-Status und einer Meldung.

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

          Tom

          1. Hello,

            zuerst mal danke für deine Hilfe. wenn ich mir das so ansehe, vermute ich aber, dass ich die "Betitelung" der Checkboxen anders machen muss - oder können die trotzdem $ger1 bis $gern heissen?

            Nur im HTML-Form

            <input type="checkbox" name="ger[1]">
              <input type="checkbox" name="ger[2]">
              ...
              <input type="checkbox" name="ger[20">

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

            Tom

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

        2. echo $begrüßung;

          $where = "";
              foreach($POST['ger'] as $key => $val)
                $where .= " and ger".intval($key)." = 1";

          Du erzeugst mit diesem Konstrukt ein überflüssiges "and" und musst das irgendwie behandeln.

          $sql = "select $fieldlist from $table where true $where";

          Du entscheidest dich dafür, ein "true" einzufügen, was weiter keine Aufgabe hat, als dem "and" einen Partner zu bieten.

          Meine Vorgehensweise in solchen Fällen ist, die Bedingungen ohne Bindewörter zu erstellen, und sie in einem Array abzulegen. Dieses implodiere ich mit dem Bindewort als "Kleber".

          $where = array();
          foreach($POST['ger'] as $key => $val)
            $where .= "ger".intval($key)." = 1";

          $sql = "select $fieldlist from $table where " . implode(' and ', $where);

          Das ist natürlich so nur verkürzt dargestellt, denn wenn man richtig mach  will, müsste man auch noch überprüfen, ob die Spalte, die man in der Foreach-Schleife baut, überhaupt im Satzformat der Tabelle vorhanden ist. Anderenfalls bestraft Dich spätestens die SQL-Abfage mit einem Fehler-Status und einer Meldung.

          Vor allem dann, wenn bei nicht numerischem $key das intval() eine 0 zurückliefert. Falls es eine Spalte ger0 gibt, ist das ein besonders hinterlistiger Fehler, der im Stillen arbeitet und "nur" zu einem falschen Abfrageergebnis führt.

          echo "$verabschiedung $name";

          1. Hello,

            $where = array();
            foreach($POST['ger'] as $key => $val)
              $where .= "ger".intval($key)." = 1";    ## hab ich noch nicht ausprobiert, aber hier

            ## würde ich selbst von PHP einen Fehler erwarten
                $where[] = "ger".intval($key)." = 1";   ## halte ich für besser

            $sql = "select $fieldlist from $table where " . implode(' and ', $where);

            Und wenn das Array leer war, weil gar kein Schalter gesetzt war, steht dann da:

            $sql = "select $fieldlist from $table where ";

            Das gibt dann einen fehler vom DBMS ;-)

            Vor allem dann, wenn bei nicht numerischem $key das intval() eine 0 zurückliefert. Falls es eine Spalte ger0 gibt, ist das ein besonders hinterlistiger Fehler, der im Stillen arbeitet und "nur" zu einem falschen Abfrageergebnis führt.

            eine der Grundregeln beim Datenbank-Programmieren ist, dass 0 beim Indizieren einen nicht gültigen Wert symbolisiert ;-) Jetzt frag bloß nicht, wo das steht. Das habe ich mir doch gerade erst ausgedacht...

            Du hast Recht, darauf hätte ich ihn hinweisen müssen.

            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 Forum,

              $where = array();
                $where .= "ger".intval($key)." = 1";    ## hab ich noch nicht ausprobiert, aber hier
                                                          ## würde ich selbst von PHP einen Fehler erwarten
                  $where[] = "ger".intval($key)." = 1";   ## halte ich für besser

              aber ich habe es ben mal ausprobiert.

              <?php
                error_reporting(E_ALL);

              $where = array();

              $where .= 'ergebnis_1';
                $where .= 'ergebnis_2';

              echo "<h1>$where</h1>\n<pre>\n";
                print_r($where);
                echo "\nTyp ist ".gettype($where);
                echo "</pre>\n";

              ?>

              Ergibt ein witziges aber gefährliches Ergebnis:

              $where
                Arrayergebnis_1ergebnis_2
                Typ ist string

              Notice gab es nicht. Das leere Array wurde einfach in einen String umgewandelt und der Typbezeichner gleich als Vorbelegung für den text benutzt *gg*

              Das war also tatsächlich falsch.

              LG
              Chris

            2. echo $begrüßung;

              $where = array();
                $where .= "ger".intval($key)." = 1";    ## hab ich noch nicht ausprobiert, aber hier
                                                          ## würde ich selbst von PHP einen Fehler erwarten
                  $where[] = "ger".intval($key)." = 1";   ## halte ich für besser

              Natürlich. War ein Copy&Paste-Fehler meinerseits.

              Und wenn das Array leer war, weil gar kein Schalter gesetzt war, steht dann da:
                $sql = "select $fieldlist from $table where ";
              Das gibt dann einen fehler vom DBMS ;-)

              Stimmt auch. Ich korrigieren zu:

              $sql = "select $fieldlist from $table" . ($where ? ' where ' . implode(' and ', $where) : '');

              echo "$verabschiedung $name";

              1. Hello,

                Stimmt auch. Ich korrigieren zu:

                $sql = "select $fieldlist from $table" . ($where ? ' where ' . implode(' and ', $where) : '');

                Habe ich natürlich auch darüber nachgedacht und es kam die Frage auf, was mehr Power kostet.
                Die zusätzliche Bedingung in PHP oder der zusätzliche Vergleich in MySQL...

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

                Tom

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

  2. Hello,

    wie weit kannst Du folgen?

    1. Wie werden Checkboxen im HTML-Formular vereinbart?

    2. Was überträgt dann der Request für die Checkboxen an das Script?

    3. Was muss man ohnehin mit übertragenen Parametern tun, bevor man sie
       in eine Datenbankabfrage übernimmt?

    4. Wie kann man mittels Vergleich entweder 0 oder 1 als Ergebnis erzeugen?

    Und dann noch ein Tipp:
    Keinen Misthaufen-Code schreiben, bei dem alles durcheinander geschieht, sondern das gute alte Prinzip

    E - Eingabe
      V - Verarbeitung
      A - Ausgabe

    beherzigen.

    • alle Usereingaben / Paramter übernehmen
    • Die übergebenen Werte kontrolliern und normieren
    • Paramter für Datenbankabfragen vorbereiten (escapen) und zusammenbauen zur Abfrage
    • Abfragen durchführen
    • Fehler-/Statuscodes auswerten und Ergebnisse übernehmen
    • Ergebnisse berechnen
    • Ausgabe vollständig zusammenbauen
    • Ausgeben

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

    Tom

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

  3. Hallo liebe Leute,

    sorry dass ich mich erst jetzt wieder melde - danke zuerst einmal für eure ganzen Tipps.

    Habe jetzt eure Ideen in mein Formular eingebaut, leider funktioniert das nicht so ganz:

    $fieldlist = "frage, antwort, datum";
      $table     = "faq";

    $where = array();
    foreach($POST['ger'] as $key => $val)
     $where[] = "ger".intval($key)." = 1";

    $sql = "select $fieldlist from $table" . ($where ? ' where ' . implode(' and ', $where) : '');

    echo $sql;

    ist meine derzeitige abfrage...und diese bringt mir folgendes Ergebnis:

    Warning: Invalid argument supplied for foreach() in abfragetest.php on line 9
    select frage, antwort, datum from faq

    irgendwas stimmt da nicht...bei meiner Abfrage war jetzt genau ein Gerät ausgesucht, wenn ich dann auf abschicken klicke bekomme ich folgende URL:

    abfragetest.php?ger%5B35%5D=on

    und das versteh ich nicht ganz, weil ich schreibe 1 und 0 in die datenbank...und nicht on, NULL

    irgendwie hab ich zur Zeit gar keinen Durchblick mehr...wer kann mir da nochmals helfen?

    Danke im voraus,
    lg, Bernhard

    1. echo $begrüßung;

      foreach($POST['ger'] as $key => $val)
      Warning: Invalid argument supplied for foreach() in abfragetest.php on line 9
      irgendwas stimmt da nicht...

      Ja, es heißt $_POST (mit Unterstrich). Wenn du beim Entwickeln das error_reporting auf E_ALL stellst, würden dir solche Schreibfehler (auch wenn es in diesem Fall nicht dein eigener war) angezeigt worden.

      echo "$verabschiedung $name";

      1. Hallo dedlfix,

        SUPER - das stimmt ja...eigentlich hätte ich das selbst sehen müssen...ES GEHT!!! *freu*

        danke vielmals für eure Hilfe,
        lg bernhard

        1. Hello,

          SUPER - das stimmt ja...eigentlich hätte ich das selbst sehen müssen...ES GEHT!!! *freu*

          danke vielmals für eure Hilfe,

          Ich hab's ja leider selber auch nicht gemerkt beim Tippen :-)

          Du solltest aber die Abfrage auf

          if(isset($_POST['ger']) and is_array($_POST['ger']))
            {

          }

          nicht vergessen, da foreach() es übel nimmt, wenn es kein Array geliefert bekommt.
          Den Frust der Fehlermeldung kann man dem User des Formulares doch ersparen, oder?

          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 :-)