Ankündigung

Einklappen
Keine Ankündigung bisher.

SQL-Abfrageergebnis mit Optionsformular verfeinern?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • SQL-Abfrageergebnis mit Optionsformular verfeinern?

    Ich lese auf der Seite index.php aus meiner Datenbank mit
    Code:
    SELECT * FROM kunden
    alle Kunden aus. Nun bekomme ich aber eine sehr große Anzahl an Kunden geliefert. Ich möchte also mit einem Optionsformular die Suche eingrenzen können:

    Code:
    <form action="index.php" method="post">
    <p>Wählen Sie eine oder mehrere Filter aus:</p>
    <p><input type="checkbox" name="vip_kunde" value="1">Kunde ist VIP-Kunde<br>
        <input type="checkbox" name="querulant" value="1">Kunde ist ein Querulant<br>
        <input type="checkbox" name="nichtzahler" value="1">Kunde schuldet uns Geld<br>
        <input type="submit" value="Filtern"/>
    </p>
    Wird der Filter angewendet, soll auch mein SQL-Query angepasst werden (In der Datenbank ist in der jeweiligen Spalte entweder eine 0 oder eine 1 hinterlegt):

    Code:
    SELECT * FROM kunden WHERE vip = $_POST['vip_kunde'] AND querulant = $_POST['querulant'] AND nichtzahler = $_POST['nichtzahler']
    .

    Wie kann ich das am elegantesten bewerkstelligen? Denn wenn beispielsweise keine Option ausgewählt und der Filtern-Button geklickt wird, wird ja in dem soeben angebenen SQL-Query ein Leerwert übergeben. Es gibt einen "Absturz". Hier kann ich natürlich ersteinmal Leerwerte herausfiltern und durch eine 0 ersetzen. Ein weiteres Problem ist dann aber, dass wenn keine Option ausgewählt wurde, ja alle Werte aus der Datenbank geholt werden sollen (also sowohl die mit einer 0, als auch mit einer 1) und nicht nur die mit einer 0.

    Ich würde gerne direkt von Anfang an sauber vorgehen, damit man die Optionen später mit möglichst geringem Aufwand erweitern kann. Habt ihr ein paar Tipps für mich?

  • #2
    Normalisieren
    Tabelle Kunden
    ID | Vorname ...| whatever

    Tabelle Kundengruppe
    GruppenID | GruppenBezeichnung | Beschreibung
    1 | VIP | ...
    2 | Querulant

    Tabelle ZuordnungKundeKundengruppe
    ZuordnungsID | KundenID | GruppenID

    PHP-Code:
    <?php
    foreach($kundenGruppen AS $kundenGruppe){
    ?>
        <input type="checkbox" name="Gruppe['<?= $kundeGruppe['ID'?>']"><?= $kundenGruppe['Beschreibung'?><br>
    <?php
    }
    ?>
        <input type="submit" value="Filtern"/>
    Über die Indizes in $_POST['Gruppe'] kommst du dann an die übergebenen IDs und kannst entsprechend die Query bauen, Stichwort Join.
    [COLOR=#A9A9A9]Relax, you're doing fine.[/COLOR]
    [URL="http://php.net/"]RTFM[/URL] | [URL="http://php-de.github.io/"]php.de Wissenssammlung[/URL] | [URL="http://use-the-index-luke.com/de"]Datenbankindizes[/URL] | [URL="https://www.php.de/forum/webentwicklung/datenbanken/111631-bild-aus-datenbank-auslesen?p=1209079#post1209079"]Dateien in der DB?[/URL]

    Kommentar


    • #3
      Danke schon mal für den Tipp mit der Extra-Tabelle. Ich grüble nun jedoch darüber nach, wie ich das mit der SQL-Query am besten mache. Gibt es eine Möglichkeit, mit der ich ich SQL-Abrage nur "einmal" im Quelltext verfassen muss und sie dann bei Programmausführung automatisch angepasst wird? Oder muss ich je nach ausgewählter Filter-Option mehrfach in sich verschachtelte IF-Klauseln programmieren (was dann ja ins bodenlose ausufern würde, wenn man später noch ein paar neue Filter-Optionen einrichtet)?

      Kommentar


      • #4
        Bin jetzt auf folgende Lösung für mein Query-Problem gekommen:

        PHP-Code:
        <?php
        if (empty($_POST['vip_kunde']))
        {
        $vip_kunde 'IN (0,1)';}
        else
        {
        $vip_kunde ' = 1';}

        $query 'SELECT * FROM kunden WHERE vip $vip_kunde';
        ?>
        So muss ich die SQL-Abfrage nur einmal schreiben und sie wird dann dynamisch ergänzt. Auch lässt sie sich problemlos um weitere Filter-Optionen erweitern. Allerdings weiß ich leider nicht, ob dass lege artis oder vielmehr größter Murks ist (auch wenn es so funktioniert)...

        Kommentar


        • #5
          An Hand der gecheckten Boxen baust du dir die jeweils passende query zusammen. Dh POST abholen und auswerten und daraus Stück für Stück den richtigen String für die DB query "zusammenbauen".

          Und SELECT * ist pfui: http://php-de.github.io/jumpto/code-smells/#select-

          LG
          The string "()()" is not palindrom but the String "())(" is.

          Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
          PHP.de Wissenssammlung | Kein Support per PN

          Kommentar


          • #6
            @hausl:

            Okay, das mit dem "SELECT * = Pfui!" sehe ich ein . Wird natürlich gleich angepasst. Aber inwieweit ist der Rest "höchst unsicher"? Eigentlich dürfte doch kein Schadcode in die SQL-Abfrage injizierbar sein. Zwar könnte ein Bösewicht irgend einen beliebigen String in $_POST['vip_kunde'] einschleusen. Allerdings würde das ja nur dazu führen, dass dann die Bedingung

            PHP-Code:
            $vip_kunde ' = 1'
            Eintritt und dieser feste Code an die SQL-Abfrage übergeben wird. An die SQL-Abfrage selbst kommt doch keiner ran. Oder sehe ich hier irgendeine Möglichkeit nicht?

            Kommentar


            • #7
              Injection-Gefahr sehe ich auch nicht.

              Was deine Lösung betrifft,
              da musst du dann entscheiden, ob du es einfach nur fertig haben willst mit einem suboptimalen Datenbankdesign, das im späteren Verlauf vielleicht nochmal für richtiges Kopfzerbrechen sorgen kann (http://de.wikipedia.org/wiki/Technische_Schuld)
              oder ob du von Anfang an versuchst der Ideallinie zu folgen und dafür dann am Beginn mehr Zeit investierst um dich in Normalisierung und das Arbeiten mit Join einzufinden.

              Ich rate natürlich zum 2., weiß aber nicht wie weit das Projekt ist, wie wichtig es ist und was deine Motivation bei der ganzen Sache ist.
              [COLOR=#A9A9A9]Relax, you're doing fine.[/COLOR]
              [URL="http://php.net/"]RTFM[/URL] | [URL="http://php-de.github.io/"]php.de Wissenssammlung[/URL] | [URL="http://use-the-index-luke.com/de"]Datenbankindizes[/URL] | [URL="https://www.php.de/forum/webentwicklung/datenbanken/111631-bild-aus-datenbank-auslesen?p=1209079#post1209079"]Dateien in der DB?[/URL]

              Kommentar


              • #8
                Zitat von VPh Beitrag anzeigen
                Ich rate natürlich zum 2., weiß aber nicht wie weit das Projekt ist, wie wichtig es ist und was deine Motivation bei der ganzen Sache ist.
                Auf jeden Fall werde ich die Datenbank mittels Zuordnungstabellen normalisieren. Ich stehe noch recht am Anfang des Projekts und wollte meine Ursprungsfrage nicht allzu sehr überladen. Allerdings ist das mit den Zuordnungstabellen ja unabhängig von dem Hauptproblem der dynamischen Erstellung der SQL-Abfrage (außer, dass dann eben JOIN und nicht WHERE dominiert). Hast Du diesbezüglich vielleicht noch einen Tipp?

                Kommentar


                • #9
                  @Injection: Richtig, ihr habt recht, Sry, keine Ahnung wo ich da hingesehen hab. Vermutlich hat mich die einsam und alleine in der query stehende Variable verwirrt und das davor hab ich übersehen... Mittagstief o.ä. Hab es oben geändert.
                  The string "()()" is not palindrom but the String "())(" is.

                  Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                  PHP.de Wissenssammlung | Kein Support per PN

                  Kommentar

                  Lädt...
                  X