Hi!
- Ich weiß nicht welches Format eine Spalte hat, muss das aber bei einem Prepared-Statement wissen.
Zahlenwerte können auch als String übergeben werden. Probier mal alle relevanten Typen aus, ob sie sich als s übergeben lassen.
- Es wird eine variable Anzahl an Spalten geupdatet.
Hier stört mich dass ich den Spaltennamen nicht als Parameter über bind() mit angeben kann, sondern jeweils einen neuen Query-String zusammenbauen muss.
Geht das doch irgendwie?
Nein, du kannst nur Werte binden, keine Bezeichner. Aber was genau stört dich? Code zu schreiben, der aus einem Array mit Spaltennamen ein INSERT-Statement zusammenbaut ist eine einmalige Angelegenheit und auch keine Raketenwissenschaft.
[code lang=php]switch($_GET['action']){
Ich würde den Code kapseln (Funktion oder Objekt) und dabei keinen direkten Zugriff auf externe Dinge verwenden, sondern alle benötigten Werte per Parameter übergeben. Dantenbankzugriff ist etwas sehr allgemeines, was man gut wiederverwenden kann, wenn man es nicht mit projektspezifischen Dingen spickt.
$stmt = $mysqli->prepare('DELETE FROM '.mysql\_real\_escape\_string($\_GET['table']).' WHERE id = ?');
Gute Idee, die Bezeichner zu maskieren, aber falsche Ausführung. Da sind gleich drei Fehler enthalten.
- mysql_real_escape_string() maskiert nur, es quotiert nicht. Wenn du keinen String einleitest, bringt es keine Punkte, stringspezifische Sonderzeichen zu behandeln. Ein Angreifer ist nämlich nicht im String-Kontext gelandet und muss daraus nicht auszubrechen versuchen. Stattdessen ist er im Code-Kontext geblieben und kann mit einem Leerzeichen getrennt nach dem Tabellennamen einfach weiterschreiben. Es fehlen also die Anführungszeichen um den Tabellennamen.
- Bezeichner werden (falls nötig - und ja, es ist in deinem Fall dringend geboten, um explizit in den Bezeichner-Kontext zu gelangen, weil du Benutzereingaben durchreichst) unter MySQL mit
Backticks
eingerahmt. Zudem folgen sie anderen Maskier-Regeln als mysql_real_escape_string() behandelt. Es gibt keine spezielle Funktion zu ihrer Behandlung, aber es reicht, einfache Backticks zu verdoppeln, was mit str_replace() machbar ist. - mysql_real_escape_string() benötigt zum Arbeiten eine Verbindung zum DBMS. Vermutlich findet es deine mysqli-Verbindung, aber genau weiß ich nicht, ob es da PHP-Extension-übergreifend vorgeht. Wenn nicht, baut es sich selbst eine auf, wozu es aber Default-Konfigurationswerte benötigt, die üblicherweise nicht gesetzt sind, was wiederum dafür spricht, dass es deine vorhandene Verbindung nimmt, sonst gäbe es nur false zurück. Jedenfalls, wenn du schon objektorientiert mit mysqli arbeitest, solltest du auch dessen Methoden verwenden. (Allgemein gesagt, denn in deinem speziellen Fall ist das Escapen mit mysqli::real_escape_string() ja nicht richtig.)
Lo!