Variable Datenbankabfrage

hawaiian

Mitglied
Hallo zusammen,

ich versuche mich seit kurzem in PHP. Mein Ziel ist es, eine Datenbankabfrage zu realisieren. Dies ist mir bis zu einem gewissen Grad auch gelungen. Mit einigen Problemem komme ich aber ohne Hilfe nicht weiter. Nachfolgend die chronologische Auflistung des Codes (aus meiner Sicht nicht relevanten Code habe ich weggelassen):

PHP:
if (!isset($_POST["submit"]));
if (!isset($_POST["name"]))
{

Es folgt nun die Formularabfrage:

HTML:
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<table border="0" cellpadding="3" cellspacing="1">
  <tr>
      <td align="right">Name&nbsp;</td>
      <td><input type="text" name="name" size="25" maxlength="35" style="width:158px;" value="" /></td>
  </tr>
  <tr>
      <td align="right">Geschlecht&nbsp;</td>
      <td><input type="radio" name="geschlecht" value="m"> m&auml;nnlich
          <input type="radio" name="geschlecht" value="w"> weiblich</td>
  </tr>
  <tr>
      <td align="right">Nation&nbsp;</td>
      <td><select name="nation" size="1" style="width:165px;">
                 <option value="">--------- Auswahl ---------</option>
                 <option>CAN</option>			
                 <option>GBR</option>			
                 <option>USA</option>
              </select>
	  </td> 
   </tr>
   <tr> 
      <td align="right">Song&nbsp;</td>
      <td><input type="text" name="song" size="25" maxlength="35" style="width:158px;" value="" /></td>
  </tr>
  <tr>
      <td align="right">USA&nbsp;</td>
      <td><select name="usa" size="1" style="width:165px;">
                 <option value="">--------- Auswahl ---------</option>
                 <option>1957</option>
                 <option>1959</option>
                 <option>1967</option>
                 <option>1991</option>
              </select></td>   
  </tr>
  <tr>
      <td align="right">GBR&nbsp;</td>
      <td><select name="gbr" size="1" style="width:165px;">
                <option value="">--------- Auswahl ---------</option>
	<option>1957</option>
	<option>1959</option>
	<option>1964</option>
	<option>1991</option>
             </select></td>   
  </tr>
  <tr> 
      <td align="right">Charts USA&nbsp;</td>
      <td>
          <input type="checkbox" name="usaplatz[]" value="1" />&nbsp;Platz 1<br />
          <input type="checkbox" name="usaplatz[]" value="2" />&nbsp;Platz 2<br />
          <input type="checkbox" name="usaplatz[]" value="3" />&nbsp;Platz 3
      </td>
  </tr>
  <tr> 
      <td align="right">Charts GBR&nbsp;</td>
      <td>
         <input type="checkbox" name="gbrplatz[]" value="1" />&nbsp;Platz 1<br />
         <input type="checkbox" name="gbrplatz[]" value="2" />&nbsp;Platz 2<br />
         <input type="checkbox" name="gbrplatz[]" value="3" />&nbsp;Platz 3
     </td>
  </tr>
  <tr> 
      <td>&nbsp;</td>
      <td>
         <input type="submit" name="form" style="font-size:0.95em; width:115px; height:22px;" value="Abfrage senden" />
      </td>
  </tr>
</table>
</form>

PHP:
} else {
echo "<table border='0' cellspacing='1' cellpadding='2'>
         <tr class='ueberschrift1'>
            <th colspan='4'>Sie suchten nach</th>
			<td style='width:20px; background-color:#54A6A5'></td>
			<td style='background-color:#54A6A5'>
			    <form method='POST' action=$_SERVER[PHP_SELF]>
			    <input type='submit' name='submit' value='Erneute Suche'>
                </form></td>
         </tr>
         <tr class='zeile1'>
	        <td>Name:</td>
	        <td style='color:#FF0000'>$_POST[name]</td>
		    <td>Geschlecht:</td>
	        <td align='center' style='color:#FF0000'>$_POST[geschlecht]</td>  # Notice: Undefined index: geschlecht
         </tr>
         <tr class='zeile1'>
	        <td>Nation:</td>
	        <td style='color:#FF0000'>$_POST[nation]</td>
            <td>Song:</td>
            <td style='color:#FF0000'>$_POST[song]</td>
         </tr>
         <tr class='zeile1'>
            <td>USA:</td>
	        <td style='color:#FF0000'>$_POST[usa]</td>
            <td>GBR:</td>
	        <td style='color:#FF0000'>$_POST[gbr]</td>
         </tr>
         <tr class='zeile1'>
            <td>Charts USA:</td>
	        <td style='color:#FF0000'>$_POST[usaplatz]</td>  # Notice: Undefined index: usaplatz 
            <td>Charts GBR:</td>
	        <td style='color:#FF0000'>$_POST[gbrplatz]</td>  # Notice: Undefined index: gbrplatz 
         </tr>
      </table>";
}

$fehler        = false;
$fehlerhinweis = "";

if (empty ($_POST['name']) == TRUE AND empty ($_POST['geschlecht']) == TRUE AND empty ($_POST['nation']) == TRUE AND empty ($_POST['song']) == TRUE
AND empty ($_POST['usa']) == TRUE AND empty ($_POST['usaplatz']) == TRUE AND empty ($_POST['gbr']) == TRUE AND empty ($_POST['gbrplatz']) == TRUE) {
    $fehler        = TRUE;
    $fehlerhinweis = "Bitte auswählen. ";
  }
 
if ($fehler) {
 echo "<p>$fehlerhinweis</p>";
} else {

$link = mysql_connect("localhost", "root", "");
  if (!$link)
    die("Kann den Server nicht erreichen.");
  if (!mysql_select_db("sport", $link))
    die("Kann die Datenbank nicht anwählen.");

PHP:
$abfrage = "SELECT name, vorname, geschlecht, nation, song, usa, usaplatz, gbr, gbrplatz
            FROM musik
			WHERE 
            (name LIKE '%" . mysql_real_escape_string($_POST['name']) . "%')
            AND (geschlecht LIKE '%" . mysql_real_escape_string($_POST['geschlecht']) . "')  # Notice: Undefined index: geschlecht
            AND (nation LIKE '%" . mysql_real_escape_string($_POST['nation']) . "')
            AND (song LIKE '%" . mysql_real_escape_string($_POST['song']) . "%')
            AND (usa LIKE '%" . mysql_real_escape_string($_POST['usa']) . "')
          # AND (gbr LIKE '%" . mysql_real_escape_string($_POST['gbr']) . "')
            AND (usaplatz LIKE '%" . mysql_real_escape_string($_POST['usaplatz']) . "')      # Notice: Undefined index: usaplatz
          # AND (gbrplatz LIKE '%" . mysql_real_escape_string($_POST['gbrplatz']) . "')      # Notice: Undefined index: gbrplatz
			ORDER BY name, song ASC LIMIT 0, 60";

Die Datenbankabfrage soll in jedweder Kombination (wie viele das sind, habe ich jetzt allerdings nicht ausgerechnet) die entsprechenden Resultate auflisten. Dies klappt auch mit den ersten fünf Rubriken "name", "geschlecht", "nation", "song" und "usa" oder alternativ zu "usa" "gbr". Sobald ich aber in obige Abfrage gbr aufnehme (als Kommentar gekennzeichnet), wird kein Ergebnis mehr geliefert. "usa" und "gbr" schließen sich also gegenseitig aus. Warum das so ist, ist mir ein Rätsel.
Verbleiben noch die Checkboxen. Egal, was ich ankreuze, erscheinen alle in der Datenbank enthaltenen Datensätze.

Nun meine Fragen:
1. Wie muss ich meine Abfrage zu "usa" und zu "gbr" modifizieren, damit das geschilderte Problem nicht mehr auftritt?
2. Wie muss die Abfrage der Checkboxen richtig lauten bzw. wo baue ich welchen Code (array?) ergänzend ein?
3. Zu "geschlecht", "usaplatz", "gbrplatz" (jeweils als Kommentar kenntlich gemacht) wird undefined index moniert. Ich habe schon einige Varianten (isset?) an unterschiedlichen Stellen ausprobiert, leider ohne Erfolg. Wo muss ich welchen Code einfügen, damit diese Meldungen unterbleiben?

Jetzt ist das Posting etwas lang geworden. Ich hoffe dennoch, dass ich mein Problem verständlich darstellen konnte und hoffe auf Hilfe.

Viele Grüße
hawaiian
 
Ich vermute, dass es am "AND" liegt. Denn du kannst ja nur "usa" oder "gbr" nehmen, aber nicht beides! Du müsstest beides in einem OR klammern.

Undefined Index wird ausgespuckt, weil diese Werte im Array nicht vorhanden sind. Überprüfe mal dein Formular und was alles ankommt.

Habe jetzt nicht alles beantwortet, weil ich momentan nicht sehr viel Zeit habe.
 
Grundsätzlich solltest du nur diejenigen Kriterien in das Query übernehmen die auch abgefüllt sind. Hier mal ein Beispiel
PHP MySQL Einfacher SQL-Filter aus $_POST zusammenstellen

Und der Array der Checkboxen könnte zu folgendem umgeschrieben werden
SQL:
WHERE feld IN (1,2,3)
Und so kannst du das in PHP umsetzen
PHP:
$wheres[] = 'usaplatz IN ('.implode(',', $_POST['usaplatz']).')';
 
Zuletzt bearbeitet von einem Moderator:
Hallo ComFreek,

vielen Dank für deinen Tipp. Mit OR schließen sich zwar "usa" und "gbr" nicht mehr aus. Dafür erscheinen Datensätze, die nicht der Abfrage entsprechen. Ich komme da momentan nicht weiter.

Hallo Yaslaw,

entsprechend deinem Lösungsvorschlag habe ich meinen Code wie folgt geändert:

PHP:
    $wheres = array();

     if($_POST['name']) $wheres[] = "name='{$_POST['name']}'";
     if($_POST['geschlecht']) $wheres[] = "geschlecht='{$_POST['geschlecht']}'";
     if($_POST['nation']) $wheres[] = "nation='{$_POST['nation']}'";
     if($_POST['song']) $wheres[] = "song='{$_POST['song']}'"; 
     if($_POST['usa']) $wheres[] = "usa={$_POST['usa']}";
     if($_POST['gbr']) $wheres[] = "gbr={$_POST['gbr']}";
  // $wheres[] = 'usaplatz IN ('.implode(',', $_POST['usaplatz']).')'; 
  // $wheres[] = 'gbrplatz IN ('.implode(',', $_POST['gbrplatz']).')';

     if(count($wheres)>0) $wherestring = "WHERE ".implode(' AND ', $wheres);

$link = mysql_connect("localhost", "root", "");
  if (!$link)
    die("Kann den Server nicht erreichen.");
  if (!mysql_select_db("sport", $link))
    die("Kann die Datenbank nicht anwählen.");

$abfrage = "SELECT name, vorname, geschlecht, nation, song, usa, usaplatz, gbr, gbrplatz
            FROM musik
            {$wherestring}
            ORDER BY name, song ASC LIMIT 0, 60";

"usa" und "gbr" schließen sich nun auch nicht mehr gegenseitig aus. Damit bin ich dank deiner Hilfe schon einen Schritt weiter. Ergänze ich aber den Code nun um "$wheres[] = 'usaplatz ..." (wie oben als Kommentar dargestellt), kann ich zwar die entsprechenden Daten abfragen (also "usaplatz"), bei jeder anderen Einzelabfrage (also z. B. "Geschlecht") erscheint aber die Fehlermitteilung "Warning: implode() [function.implode]: Invalid arguments passed".
In Kombination (z. B. "geschlecht" + "usaplatz") dagegen funktioniert die Abfrage. Ergänze ich dann den Code zusätzlich um "$wheres[] = 'gbrplatz ..." (ebenfalls oben als Kommentar dargestellt), ist gar keine Datenabfrage mehr möglich. Es kommt die gleiche Fehlermitteilung.

Welcher Fehler verbirgt sich da noch?

Ich arbeite noch an einer weiteren Datenbank mit vergleichbarem, aber etwas umfangreicherem Formular. Dort funktioniert die Abfrage der Checkboxen gar nicht (Fehlermitteilung Unknown column 'Gold' in 'where clause'). Ich vermute, das liegt daran, dass die Checkboxen keine Zahl, sondern Text enthalten. Wie muss ggf.
Code:
$wheres[] = 'usaplatz IN ('.implode(',', $_POST['usaplatz']).')';
angepasst werden?

Und noch eine Frage:
Bei der Namensabfrage soll die Eingabe von drei Buchstaben genügen. Dies habe ich in meinem Ursprungscode auch hinbekommen. Wo aber muss ich hier die %-Zeichen setzen? Meine Versuche blieben leider ohne Erfolg.

Viele Grüße
hawaiian
 
Das Letzte zuerst
PHP:
if($_POST['name']) $wheres[] = "name LIKE '%{$_POST['name']}%'";

Bei $wheres[] = 'usaplatz IN ('.implode(',', $_POST['usaplatz']).')'; prüfst du nicht ob $_POST['usaplatz'] überhaubt was beinhaltet. Natürlich musst du das noch prüfen. Wenn keine Checkbox für usaplatz gesetzt ist, dann ist $_POST['usaplatz'] leer.

PHP:
if($_POST['usaplatz']) $wheres[] = 'usaplatz IN ('.implode(',', $_POST['usaplatz']).')';
 
Yaslaw, recht herzlichen Dank. Beide Codes klappen nun bestens.

Darf ich, ich hoffe abschließend, nochmals meine obige zweite Frage mit modifiziertem Code zitieren?

Ich arbeite noch an einer weiteren Datenbank mit vergleichbarem, aber etwas umfangreicherem Formular. Dort funktioniert die Abfrage der Checkboxen gar nicht (Fehlermitteilung Unknown column 'Text' in 'where clause'). Ich vermute, das liegt daran, dass die Checkboxen keine Zahl, sondern Text enthalten. Wie muss ggf.

PHP:
if($_POST['os']) $wheres[] = 'os IN ('.implode(',', $_POST['os']).')';

angepasst werden?
 
Entweder du setzt alle Werte in ' oder wenn die Texte keine Kommas haben können, dann kannst du auch mit FIND_IN_SET() arbeiten.

PHP:
if($_POST['os']){
  foreach($_POST['os'] as $item){
    $os[] = "'{$item}'";
  }
  $wheres[] = 'os IN ('.implode(',',$os).')';
}

//oder
if($_POST['os']) $wheres[] = "FIND_IN_SET(os,'".implode(',', $_POST['os'])."')";
 
Ich habe jetzt beide Codes ausführlich in meinen beiden Datenbankabfragen mit folgendem Ergebnis getestet:


Beide Codes funktionieren auch bei Checkboxen, die nur Zahlen enthalten.


Die Fehlermitteilung "Unknown column 'Text' in 'where clause'" erscheint nicht mehr.


Aber: Bei Checkboxen mit hinterlegtem Text wird kein Ergebnis ermittelt.


An was könnte dies noch liegen?
 
Mit hinterlegtem Text meine ich die value-Angaben Gold, Silber, Bronze wie im folgenden Formularausschnitt dargestellt.

HTML:
<input type="checkbox" name="os[]" value="Gold" />&nbsp;Gold<br />
<input type="checkbox" name="os[]" value="Silber" />&nbsp;Silber<br />
<input type="checkbox" name="os[]" value="Bronze" />&nbsp;Bronze

Stehen dort Zahlen, also z. B. 1, 2, 3 wie in meiner anderen Datenbankabfrage, funktionieren alle deine Codes, also

PHP:
if($_POST['os']) $wheres[] = 'os IN ('.implode(',', $_POST['os']).')';

und

PHP:
if($_POST['os']) $wheres[] = "FIND_IN_SET(os,'".implode(',', $_POST['os'])."')";

und auch

PHP:
if($_POST['os']){
    foreach($_POST['os'] as $item){
    $os[] = "'{$item}'";
    }
    $wheres[] = 'os IN ('.implode(',',$os).')'; }

Der Abruf schaut, etwas gekürzt, also so aus:

PHP:
     $wheres = array();
     ...
     if($_POST['jahros']) $wheres[] = "jahros='{$_POST['jahros']}'";
     ...
     if($_POST['os']) $wheres[] = "FIND_IN_SET(os,'".implode(',', $_POST['os'])."')";  // = eines der drei o. a. Codes

     if(count($wheres)>0) $wherestring = "WHERE ".implode(' AND ', $wheres);

$link = mysql_connect("localhost", "root", "");
  if (!$link)
    die("Kann den Server nicht erreichen.");
  if (!mysql_select_db("sport", $link))
    die("Kann die Datenbank nicht anwählen.");    
?>

<?php
$abfrage = "SELECT name, ..., os
            FROM tabelle
           {$wherestring}
           ORDER BY name, ... ASC LIMIT 0, 60";
 
Zurück