2010-12-27 13 views
3

Ich versuche herauszufinden, wie ich mein History-Skript von mysql_query() zu PDO konvertieren. Ich habe ein Formular mit 4 Eingabefeldern, die Sie beliebig auswählen können. Das bedeutet, dass 0, 1, 2, 3, 4 Felder ausgewählt werden können, abhängig davon, welche Informationen Sie erhalten möchten.Dynamische Abfragen mit PHP PDO

Ich habe versucht, db wie folgt abfragen:

$q = $db->prepare('SELECT date, 
          name, 
          action 
        FROM history 
        WHERE name = :name 
        AND action = :action'); 

$q->bindParam(':name', $Name, PDO::PARAM_STR, 20); 
$q->bindParam(':action', $Action, $PDO::PARAM_STR, 20); 
$q->execute(); 

Aber das funktioniert nicht, wenn ich keine Felder ausgewählt und wollen die ganze Geschichte gezeigt.

mit mysql_query() Ich würde dies nur tun:

mysql_query('SELECT date, 
        name, 
        action 
      FROM history 
      $Name 
      $Action'); 

Was bedeutet, wenn es keine $ Name ist oder $ Aktion sie einfach nicht in der Abfrage enthalten.

Sollte ich nur die alte Abfrage in $ q = $ db-query ('') kopieren/einfügen? Aber diese Art von besiegt den Zweck der Verwendung von PDO.

Antwort

10

Sie können den Parametern, die den Spaltennamen entsprechen, immer Standardwerte zuweisen.

Auf diese Weise endet Ihre Abfrage im Standardfall als where column = column und wenn ein Wert vorhanden ist, wird es where column = value sein.

EDIT:

Natürlich war meine Logik leicht fehlerhaft, da bindParam nicht so. Stattdessen sollten Sie Ihre Anweisung inkrementell gemäß dem Parametersatz erstellen.

/* Start with the most general case for the sql query. 
* The where part always evaluates to true and will thus 
* always return all rows and exists only to make appending 
* further conditions easier. 
*/ 

$q = 'SELECT date, name, action FROM history WHERE 1'; 

/* Prepare a params array in any way you wish. A loop might be more 
* efficient if it is possible, but since in this example you have 
* only 2 variables, it didn't seem necessary 
*/ 

$params = array(); 
if (! empty($Name)) { 
    $params['name'] = $Name; 
} 

if (! empty($Action)) { 
    $params['action'] = $Action; 
} 

/* When the params array is populated, complete the sql statement by 
* appending the param names joined with ANDs 
*/ 

foreach ($params as $key => $value) { 
    $q .= sprintf(' AND `%s` = :%s', $key, $key); 
} 

/* When the query is complete, we can prepare it */ 
$stmt = $db->prepare($q); 

/* Then bind the values to the prepared statement 
*/ 

foreach ($params as $key => $value) { 
    // Using bindValue because bindParam binds a reference, which is 
    // only evaluated at the point of execute 
    $stmt->bindValue(':'.$key, $value); 
} 

/* Now we're ready to execute */ 
$stmt->execute(); 

In diesem Beispiel ist die empty Prüfung in der Schleife gemacht habe könnte, wo wir die SQL-Anweisung abgeschlossen hat, aber das würde man ein weniger allgemeines Beispiel hat gegeben.

Dieses Beispiel lässt auch den Typ param zu bindValue aus, aber das würde leicht implementiert werden, z. indem Sie den Array-Wert in ein Objekt oder Array ändern, das den Typ als Mitglied hat, oder indem Sie in der Zuweisungsschleife durch die Eingabe tippen.

Die Abfrageerstellung könnte in dieser Form leicht in eine Funktion gestellt werden, die für alle Ihre Datenbankabfrageanforderungen funktioniert, solange Sie die erste (allgemeine Fall-) Abfrage zusammen mit dem params -Array bereitstellen.

+0

Ich habe versucht, nur ein Leerzeichen hinzuzufügen, wenn die Variable leer ist. Hat nicht funktioniert. –

+0

Ein Leerzeichen ist ein Wert und stimmt daher nur mit Spalten überein, die diesen Wert enthalten, aber eine Spalte stimmt immer mit sich selbst überein. –

+0

Ich habe deine Lösung in phpmyadmin versucht, funktioniert perfekt. Jetzt ist das einzige Problem, dass wenn ich bindParam sie in '' eingeschlossen werden, die es nicht eine Spalte aber ein Suchwort macht. Irgendwelche Ideen, wie man diese entfernen kann? Ich verwende PDO :: PARAM_STR, wenn ich es binde. –