======[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]]