User Tools

Site Tools


php:kompost:variablewherefrompost

[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)
<?php
define ('DATE_PATTERN', '/^([[:digit:]]{1,2})\.([[:digit:]]{1,2})\.([[:digit:]]{4})$/');
define ('DATE_REPLACE', '$3-$2-$1');
// Diese Zeile simuliert die Post-Übergabe eines Formulars
$_POST = array(
	'name'=>'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

php/kompost/variablewherefrompost.txt · Last modified: 11.12.2013 14:21:08 (external edit)