======[PHP] [MySQL] Variable Where mit Daten aus $_POST======
=====Problemstellung=====
Man hat eine Suchmaske um mehrere Felder nach verschiedenen Kriterien zu durchsuchen. Jedoch muss nicht jeder Suchbegriff eingegeben werden.
=====Lösung=====
Dies ist eine relative komplexe Lösung. Am besten vorher mal "[[PhpPost2Var]]" und "[[PhpVariableWhereSimple]]" durchgehen, denn diese beiden Ansätze sind hier ebenfalls mit eingebaut.
====Definitionen====
(php;1)
'user',
'firma'=>'"Text mit Werten welche mit
mysql_real_escape_string() geparst werden müssen/"',
'standort'=>'',
'datumv' =>array('15.2.2010'),
'unbekanntesFeld' => 'irgend was unerwünschtes');
====Die Funktionen====
(php;12)
/**
* Funktion um aus den Werten je nach Datentyp einen richtigen SQL-WHERE - Teil zu bilden.
*/
function createWherePart(&$wert, $spalte){
switch($GLOBALS['allowedPost'][$spalte]){
case 'daterange':
if ($wert[0]) $von = preg_replace(DATE_PATTERN, DATE_REPLACE, $wert[0]);
if ($wert[1]) $bis = preg_replace(DATE_PATTERN, DATE_REPLACE, $wert[1]);
if($wert[0] && $wert[1]){
$wert = "{$spalte} BETWEEN '{$von}' AND '{$bis}'";
} elseif ($wert[0]){
$wert = "{$spalte} >= '{$von}'";
}
break;
case 'date':
//TODO: Format noch anpassen. Ist nicht umbedingt MySQL-Konform
$wert = "{$spalte} = ".preg_replace(DATE_PATTERN, DATE_REPLACE, $wert);
break;
case 'number':
$wert = "{$spalte} = {$wert}";
break;
case 'string':
$wert = "{$spalte} LIKE '{$wert}%'";
}
}
function escapeString(&$value){
$value = mysql_real_escape_string($value);
}
====Anwendung====
(php;42)
//Erwartete Felder und ihr Datentyp
$whitelist = array(
'name' => 'string',
'firma' => 'string',
'standort' => 'string',
'datumv' => 'daterange');
//Die Connection baue ich hier nur auf, um den mysql_real_escape_string() zu
//ermöglichen. Diese sollte gerade bei WHERE-Feldern unbedingt genutzt werden
$conn = mysql_connect('localhost', 'root', '') or die(mysql_error);
//Array erstellen mit allen übergebenen Variablen die in $whitelist definiert sind
//Mehr dazu: http://wiki.yaslaw.info/wikka/PhpPost2Var
//array_intersect_key entfernt nicht definierte Post-Values. In meinem Beipsiel 'unbekanntesFeld'
//array_filter ohne Filterfunktion filter alle leeren Einträge aus. in diesem Fall 'standort'
$wheres = array_filter(array_intersect_key($_POST, $whitelist));
//alle WHERE-Werte mit mysql_real_escape_string parsen um bösartige Zugriffe zu unterbinden
array_walk_recursive($wheres, 'escapeString');
//Alle Wheres formatieren
array_walk($wheres, 'createWherePart');
//Alle Wheres mit 'AND' zusammenfügen ...
$where = implode(' AND ', $wheres);
//... und ggf den Befehl WHERE voranstellen
if($where) $where = "WHERE {$where}";
//SQL erstellen
$sql = "SELECT *
FROM projekte
{$where}";
//TODO Auswertend des SQLs
//Für deises Testscript reicht jedoch die Ausgabe unseres Sqls
echo $sql;
//Datenbankconnection wieder schliessen
mysql_close($conn);
?>
Die Ausgabe von diesem Script sieht so aus (Habs von Hand rasch formatiert, damit es lesbarer ist. Die eigentliche Ausgabe ist ein Einzeiler):
SELECT *
FROM projekte
WHERE
name LIKE 'user%'
AND firma LIKE '\"Text mit Werten welche mit \r\n mysql_real_escape_string() geparst werden müssen/\"%'
AND datumv >= '2010-2-15'
----
Kategorien: [[CatPhp]] | [[CatMySql]]