Schwieriges Problem mit addslashes()
Gerhard
- php
Hallo,
ich habe ein äußerst hinterlistiges Problem:
Um einen String in eine mySQL-Datenbank zu schreiben, schütze ich diesen zuvor mit addslashes(). Sehe ich mir den Inhalt der Datenbank sogleich an, sehe ich, dass die Backslashes erfolgreich hinzugefügt wurden um ersichtlich sind.
Ich habe jetzt bei einem Projekt eine Art Datenbank-Backup mit Hilfe des Dateisystems implementiert. D.h. im Groben, dass ich die Datenbank auslese, in CREATE- und INSERT-Befehle umwandle und diese in einer Datei ablege. Sehe ich mir diese Datei mit einem Wordpad an, stehen hier auch noch korrekterweise die Backslashes an der gewünschten Position dabei.
Will ich diese Datei nun wieder importieren, lösche ich zuerst sämtliche Tabellendefinitionen der Datenbank und führe die in der Datei befindlichen SQL-Anweisungen aus. Jetzt ist da allerdings das Problem aufgetaucht, dass er beim einlesen der Datei in mein PHP-Skript irgendein grausiges Spiel mit meinen Backslashes treibt. Das komische daran ist, dass er sie nicht ganz weglässt, sonst würde bereits dieser Vorgang einen mySQL-Fehler nach sich ziehen. Aber nach dem INSERT sind diese Escape-Backslashes in der Datenbank nicht mehr vorhanden.
D.h. kommt es nun zu einem weiteren Export und wiederum Import, stehe ich vor dem Fehler, dass die Strings nicht mehr mit Backslashes geschützt sind.
Was macht PHP da beim Einlesen von Dateien, dass dieses Phänomen auftritt? Hat irgendwer Ideen wo der Hund begraben sein könnte?
Danke im Voraus
lg Gerhard
Moin!
ich habe ein äußerst hinterlistiges Problem:
Eigentlich nicht.
Um einen String in eine mySQL-Datenbank zu schreiben, schütze ich diesen zuvor mit addslashes().
Und das ist schon mal falsch. Verwende immer und ausschließlich mysql_real_escape_string().
Sehe ich mir den Inhalt der Datenbank sogleich an, sehe ich, dass die Backslashes erfolgreich hinzugefügt wurden um ersichtlich sind.
Und das ist auch falsch, denn die Backslashes sollten durch den SQL-Parser erkannt und aus den in die DB eingetragenen Daten entfernt worden sein. Wenn du die Daten wieder ausliest, sollen eben gerade KEINE Backslashes mehr zu sehen sein - jedenfalls nicht die, die durch das Escaping eingetragen wurden - wenn in den Daten Backslashes vorkommen, müssen die natürlich erhalten bleiben.
Ich habe jetzt bei einem Projekt eine Art Datenbank-Backup mit Hilfe des Dateisystems implementiert. D.h. im Groben, dass ich die Datenbank auslese, in CREATE- und INSERT-Befehle umwandle und diese in einer Datei ablege. Sehe ich mir diese Datei mit einem Wordpad an, stehen hier auch noch korrekterweise die Backslashes an der gewünschten Position dabei.
In dieser Datei, die fertige SQL-Befehle enthält, müssen die Escape-Zeichen natürlich wieder auftauchen.
Will ich diese Datei nun wieder importieren, lösche ich zuerst sämtliche Tabellendefinitionen der Datenbank und führe die in der Datei befindlichen SQL-Anweisungen aus. Jetzt ist da allerdings das Problem aufgetaucht, dass er beim einlesen der Datei in mein PHP-Skript irgendein grausiges Spiel mit meinen Backslashes treibt. Das komische daran ist, dass er sie nicht ganz weglässt, sonst würde bereits dieser Vorgang einen mySQL-Fehler nach sich ziehen. Aber nach dem INSERT sind diese Escape-Backslashes in der Datenbank nicht mehr vorhanden.
Dann hast du ein Problem mit korrektem Escaping.
D.h. kommt es nun zu einem weiteren Export und wiederum Import, stehe ich vor dem Fehler, dass die Strings nicht mehr mit Backslashes geschützt sind.
Klarer Fall von "Ein Escaping zu wenig" - was wiederum darauf hindeutet, dass dein normaler Mechanismus offenbar dieses Escaping zusätzlich macht - und das deutet wiederum darauf hin, dass du wahrscheinlich auf einem PHP-System arbeitest, bei dem magic_quotes_gpc eingeschaltet ist und dir somit alle Daten, die per Formular gesendet werden, schon mal automatisch mit einem Escaping versehen werden.
Das erklärt auch, warum du nach addslashes() immer noch Slashes in der DB siehst.
Für den Export in SQL-Statements gilt vor dem Speichern des fertigen INSERT dasselbe.
- Sven Rautenberg
echo $begrüßung;
Um einen String in eine mySQL-Datenbank zu schreiben, schütze ich diesen zuvor mit addslashes().
adslashes ist nicht wirklich dafür geeignet, da es weniger Zeichen behandelt, als für MySQL erforderlich sind. Nutze mysql_real_escape_string().
Sehe ich mir den Inhalt der Datenbank sogleich an, sehe ich, dass die Backslashes erfolgreich hinzugefügt wurden um ersichtlich sind.
Wenn du sie in der Datenbank siehst, hat sicherlich noch das Feature Magic Quotes zugeschlagen, welches dafür sorgt, dass GPC-Werte schon von vorn herein mit adslashes() behandelt wurden.
Wenn du einen SQL-Befehl notierst ist das ein Text. Möchte man Bezeichner von Nutzdaten unterscheiden muss man eins von beiden besonders markieren. In dem Fall werden Nutzdaten-String-Werte in Anführungszeichen eingefasst. Nun kann es vorkommen, dass in diesem String Anführungszeichen vorkommen, die nicht das Ende des Strings markieren sollen sondern zum Inhalt gehören. Deshalb gibt es die Syntax, diesen ein \ voranzustellen. Ebenso müssen ein paar weitere Zeichen behandelt werden. PHP wollte es den Programmieren einfach machen und hat dafür Magic Quotes erfunden. Doch die behandeln sämtliche Eingabedaten und nicht nur diejenigen, die im SQL-String landen sollen, und wie gesagt, berücksichtigt dieses Feature auch noch zu wenig Zeichen. Ab PHP 6 wird es dieses Feature nicht mehr geben. Bis dahin ist meine Empfehlung, Magic Quotes auszuschalten oder seine Auswirkungen am Scriptanfang rückgängig zu machen und für die ordentliche Maskierung der Werte mittels extra dafür vorgesehener Funktionen vorzunehmen.
Diese Maskierung wird nur auf dem Weg hin zur Datenbank benötigt, denn rückwärts kommen sie nicht über eine Text-Schnittstelle.
[Problembeschreibung]
Was macht PHP da beim Einlesen von Dateien, dass dieses Phänomen auftritt? Hat irgendwer Ideen wo der Hund begraben sein könnte?
Große Teile deines Problems sollten sich von selbst erledigt haben, wenn du obige Erklärung versteht und die Magic Quotes und das addslashes() zu Gunsten von mysql_real_escape_string() hinter dir lässt.
echo "$verabschiedung $name";