Query mit IN-Klausel absichern

Gsus

schwankend^^
ID: 215354
L
22 Mai 2006
1.553
68
Hallo,

ich nutze die MySQL-Query-Funktion zum absichern meiner Querys hier aus dem Snippet-Forum. Mit leichtern Änderungen sieht diese bei mir wie folgt aus:

PHP:
public function query($query) {
     $this->_querycount++;
     $args = func_get_args();
     $vargs = array();
     for($i=1; $i<func_num_args(); $i++) {
         if(get_magic_quotes_gpc()) $args[$i] = stripslashes($args[$i]);
         $vargs[] = mysql_real_escape_string($args[$i]);
     }
     $query = vsprintf($query, $vargs);
     $result = mysql_query($query);
     if($error = mysql_error()) $this->errorlog($query, $error);
     return $result;
     mysql_free_result($result);
}

Nun habe ich das Problem, dass ich mit dieser Funktion gerne den IN-Tag in Verbindung mit einem Array-implode verwenden möchte. Dies sieht zur Zeit folgendermaßen aus:

PHP:
$result = $mysql->query("SELECT `project_name`, `db_prefix`, `root_directory` FROM `".$mysql_data['prefix']."_projects` WHERE `project_name` IN ('%s')", implode($_POST['projects'], "', '"));

Das Problem ist nun, dass die Funktion mir alle vom implode erzeugten ' escaped zu \', wodurch der Query nicht dem entspricht, was ich eigentlich haben möchte;). Das Array muss aber abgesichert sein, da ich nicht kontrollieren kann, was da für Daten gesendet werden.

Leider fällt mir gerade nicht ein, wie ich dieses Problem lösen kann, aber vielleicht habt ihr ja eine gute Idee?!

Vielen Dank im Vorraus.
Gsus
 
Du musst den Teil
Code:
'...','...','...'
vorher von Hand zusammenbauen:
Schleife + sprintf() + mysql_real_escape_string()
 
Schleife + sprintf() + mysql_real_escape_string()
Eine weitere Schleife braucht's da eigentlich nicht:
PHP:
//...
for($i=1; $i<func_num_args(); $i++) {
    if (is_array($args[$i)) {
        if(get_magic_quotes_gpc()) {
            $args[$i] = array_map('stripslashes', $args[$i]);
        }
        $vargs[] = implode("','", array_map('mysql_real_escape_string', $args[$i]));
    } else {
        if(get_magic_quotes_gpc()) {
            $args[$i] = stripslashes($args[$i]);
        }
        $vargs[] = mysql_real_escape_string($args[$i]);
    }
}
//...
 
Danke, die Lösung von tleilax funktioniert super! Die Funktion array_map() kannte ich vorher auch noch nicht, scheint aber sehr nützlich zu sein! Man lernt eben nie aus :D

Vielen Dank :)

mfg
Gsus
 
Ich halte von der obigen Funktion nichts, weil man hier versucht mit dem Golden hammer alle Anwendungsfälle zu erschlagen.
So reicht es doch aus einen Integer auf dessen Inhalt zu überprüfen oder ggf. auf Integer zu casten.

Anmerkung: Zeile 13 wird niemals ausgeführt.
 
und vergisst du es einmal an einer Stelle hast du gleich eine SQL-Injection...
Verwendest du jedoch konsequent die Funktion ist es nicht schlimm, dass du einmal die Prüfung vergessen hast.
 
Anmerkung: Zeile 13 wird niemals ausgeführt.

Ja, darüber habe ich mir auch bereits Gedanken gemacht, ob das einen Sinn hat oder nicht... Wenn ich diese Funktion allerdings vorher aufrufe, habe ich nichts mehr zu returnen :D Gibt es hierzu vielleicht auch noch Anregungen?

Ich benutze die Funktion um gegen SQL-Injections gewappnet zu sein ja.
 
Wenn ich diese Funktion allerdings vorher aufrufe, habe ich nichts mehr zu returnen :D Gibt es hierzu vielleicht auch noch Anregungen?

Ich würde sagen, es ist nicht Aufgabe der query-Funktion den Speicher freizugeben. Sonst hätte man es doch standardmäßig schon bei mysql_query eingebaut, oder? ;)
 
Ich würde sagen, es ist nicht Aufgabe der query-Funktion den Speicher freizugeben. Sonst hätte man es doch standardmäßig schon bei mysql_query eingebaut, oder? ;)
Da ist was wahres dran ja :D
aber es ist doch schon richtig, dass es ein besserer Codingstil ist, den belegten Speicher auch wieder freizugeben, wenn man ihn nicht mehr benötigt, oder? Also gibt es dafür keine andere möglichkeit, als die funktion jedesmal nach einer Query aufzurufen? Ich dachte, dass es da vielleicht etwas eleganter geht ;)

mfg
Gsus
 
Da ist was wahres dran ja :D
aber es ist doch schon richtig, dass es ein besserer Codingstil ist, den belegten Speicher auch wieder freizugeben, wenn man ihn nicht mehr benötigt, oder? Also gibt es dafür keine andere möglichkeit, als die funktion jedesmal nach einer Query aufzurufen? Ich dachte, dass es da vielleicht etwas eleganter geht ;)

Naja, also du willst ja anschließend mit dem ResultSet weiterarbeiten (also der Rückgabe von mysql_query()), somit solltest du den Speicher auch erst wieder freigeben, wenn du fertig bist mit dem weiterarbeiten.
D.h. wenn du wirklich nirgendwo mehr mit der direkten Rückgabe deiner Funktion query() arbeitest.

Ich weiß gerade auch nicht wie die Speicherverwaltung bei PHP in Verbindung mit MySQL geregelt ist und ob mysql_free_result() überhaupt noch viel bringt, oder das eh automatisch gemacht wird... ich sage mal klein: Du kannst es vernachlässigen...
Da könnte vielleicht eher ice-breaker was zu sagen? Oder hat da sonst noch wer Ahnung von? :-?
 
Ich weiß gerade auch nicht wie die Speicherverwaltung bei PHP in Verbindung mit MySQL geregelt ist und ob mysql_free_result() überhaupt noch viel bringt, oder das eh automatisch gemacht wird... ich sage mal klein: Du kannst es vernachlässigen...
So ist es auch. PHP gibt in aller Regel alle belegten Ressourcen am Skriptende automatisch frei. Würde ich demzufolge bei PHP eher als Mikrooptimierung ansehen, die man erst angehen sollte, wenn man in Speicherprobleme läuft.

Aber letztendlich ist es jedem selbst überlassen, wie er das angeht. Wer nicht überwiegend PHP spricht, wird sich vermutlich wohler fühlen, wenn er die Ressource explizit freigibt.