Hallo liebe Gemeinde,
ich melde mich mal wieder, weil ich zur Zeit ein bisher unbekanntes Problem mit einem SQL-Statement besitze und ich erstmal nicht weiter komme.
Hintergrund:
Ich habe zum Absetzen eines SQL-Statements eine Methode namens runQuery() geschrieben, die ein formuliertes SQL-Statement, als String und ein Array mit Statement-variablen übergeben bekommt, welches in der Methode zu einem String zusammen gesetzt wird und anschließend mit der sprintf-Funktion konkadiniert wird um das Statement mit dem Query-Befehl an den MYSQL-Server abzusentzen.
Den Aufwand mache ich deswegen damit ich die im Array entghaltenen Variablen - die aus einem POST kommen, mit der "real_escape_string"-Funktion filtern kann um SQL-Injection zu umgehen.
Hier der Code dazu:
Formulierung des SQL-Statements:
Model-Klasse:
Leider bekomme ich folgende Fehlermeldung zu Gesicht:
Fehlerausgabe:
Der Ausgabe-String nach Verarbeitung durch "sprintf" sieht so aus:
Ich habe auch geprüft, ob die Spalte in der Tabelle "Mitarbeiter" existiert. Die Spalten sind alle korrekt und vorhanden!
Wenn ich jetzt den Platzhalter "%s" vor dem Vornamen, im SQL-Statement in "%d" umändere, wird der Datensatz eingetragen, jedoch fehlt in der Tabelle der Namen. Stattdessen wird "0" als Namen in die Tabelle gespeichert.
Mir ist auch klar wofür %d steht, nur testhalber habe ich den für Vorname genommen um zu schauen, ob die Fehlermeldung weggeht!
Ist der Platzhalter %s für einen übergebenen String, aus einem Eingabeformular falsch gewählt? oder kommt die Funktion sprintf mit unterschiedlichen Platzhaltertypen, wie "%s" und "%d" nicht klar?
Bei einem ähnlichen Statement funktioniert die Eingabe einwandfrei!
Eingabe-Satement zum Anlegen eines Users
ich melde mich mal wieder, weil ich zur Zeit ein bisher unbekanntes Problem mit einem SQL-Statement besitze und ich erstmal nicht weiter komme.
Hintergrund:
Ich habe zum Absetzen eines SQL-Statements eine Methode namens runQuery() geschrieben, die ein formuliertes SQL-Statement, als String und ein Array mit Statement-variablen übergeben bekommt, welches in der Methode zu einem String zusammen gesetzt wird und anschließend mit der sprintf-Funktion konkadiniert wird um das Statement mit dem Query-Befehl an den MYSQL-Server abzusentzen.
Den Aufwand mache ich deswegen damit ich die im Array entghaltenen Variablen - die aus einem POST kommen, mit der "real_escape_string"-Funktion filtern kann um SQL-Injection zu umgehen.
Hier der Code dazu:
Formulierung des SQL-Statements:
PHP:
...
private function MAInput(HttpRequest $req){
...
// %d oder %s dienen als Platzhalter für die im Array enthaltenen Variablen, die nachher die Funk. sprintf-Funktion interpretiert
$sqlStatement = "INSERT INTO
mitarbeiter
SET
Anrede_ID = %d,
PersonalNummer = %d,
Vorname = %s,
PLZ = %d,
Telefon = %d,
Handy = %d ";
$parameter = array($req->getParameter('anr'), $req->getParameter('pn'),
$req->getParameter('vn'), $req->getParameter('plz'),
$req->getParameter('tel'), $req->getParameter('mobi'));
$result = AuthModel::runQuery($sqlStatement, $parameter);
var_dump($result);
...
}
Model-Klasse:
PHP:
...
public static function runQuery($statement, $arrayOfVars = array()){
$connectState = self::connectDB(....);
//Übergabeparameter auf Inhalt und Typ prüfen.
if(!empty($statement) && !empty($arrayOfVars) && is_string($statement) && is_array($arrayOfVars) && $connectState == true){
// Alle übergebenen Variablen, im Array, werden von evtl. angehängten Zeichen befreit (DB Injection)
$tempArray = array();
foreach ($arrayOfVars as $key){
array_push($tempArray, self::$resDB->real_escape_string($key));
}
//Konkadinieren des SQL-Statements und der Variablen, im Array
array_unshift($tempArray, $statement);
// Füge den konkadinierten String nun mit der formatierten Ausgabefunktion "sprintf" aus.
$statement = call_user_func_array('sprintf',$tempArray);
try{
if($result = self::$resDB->query($statement)){
//Verbindung zur Datenbank, nach Absetzen das Statements, schließen (LAZY-Pattern).
self::$resDB->close();
return 'SQL-Statement erfolgreich! ';
}else throw new \Exception('Fehler im Statement: "'.self::$resDB->error.'"');
}catch(\Exception $e){
echo $e->getMessage();
}
}
...
Leider bekomme ich folgende Fehlermeldung zu Gesicht:
Fehlerausgabe:
Code:
// Test ist der eingegebene Vorname
Fehler im Statement: "Unknown column 'Test' in 'field list'"NULL
Der Ausgabe-String nach Verarbeitung durch "sprintf" sieht so aus:
SQL:
INSERT INTO mitarbeiter SET Anrede_ID = 2, PersonalNummer = 123456, Vorname = Test, PLZ = 12345, Telefon = 1234567, Handy = 2147483647
Ich habe auch geprüft, ob die Spalte in der Tabelle "Mitarbeiter" existiert. Die Spalten sind alle korrekt und vorhanden!
Wenn ich jetzt den Platzhalter "%s" vor dem Vornamen, im SQL-Statement in "%d" umändere, wird der Datensatz eingetragen, jedoch fehlt in der Tabelle der Namen. Stattdessen wird "0" als Namen in die Tabelle gespeichert.
Mir ist auch klar wofür %d steht, nur testhalber habe ich den für Vorname genommen um zu schauen, ob die Fehlermeldung weggeht!
Ist der Platzhalter %s für einen übergebenen String, aus einem Eingabeformular falsch gewählt? oder kommt die Funktion sprintf mit unterschiedlichen Platzhaltertypen, wie "%s" und "%d" nicht klar?
Bei einem ähnlichen Statement funktioniert die Eingabe einwandfrei!
Eingabe-Satement zum Anlegen eines Users
PHP:
...
$sqlStatement = "GRANT %s ON *.* TO '%s'@'localhost' IDENTIFIED BY '%s' WITH GRANT OPTION";
$parameter = array($req->getParameter('kontotype'), $req->getParameter('userName'), $req->getParameter('userPW'));
$result = AuthModel::runQuery($sqlStatement, $parameter);
...
Zuletzt bearbeitet: