Hallo Der,
Liefert die mysqli-Schnittstelle echte Linefeeds oder auch schon die Escape-Sequenz Backslash, \n?
(Im Forum muss man Backslashes ebenfalls escapen)
Ja.
Kommt halt drauf an was in der DB steht. Und mysqli macht die Sache nicht einfacher, wenn man SQL Literale verwendet.
Ich habe mal diese Codesequenz laufen lassen:
$db->query("INSERT INTO foo (col) VALUES('1 Hello\nWorld')");
$db->query("INSERT INTO foo (col) VALUES('2 Hello\\nWorld'))";
$db->query("INSERT INTO foo (col) VALUES('3 Hello\\\nWorld'))";
$db->query("INSERT INTO foo (col) VALUES('4 Hello\\\\nWorld'))";
$db->query("INSERT INTO foo (col) VALUES('5 Hello\\\\\nWorld'))";
$db->query("INSERT INTO foo (col) VALUES('6 Hello\\\\\\nWorld'))";
$db->query("INSERT INTO foo (col) VALUES('7 Hello\\\\\\\nWorld'))";
$db->query("INSERT INTO foo (col) VALUES('8 Hello\\\\\\\\nWorld'))";
Wenn man überlegt, was PHP daraus macht, werden dadurch die folgenden SQL Statements an die DB geschickt. Linefeeds im Statement sind Linefeeds, die die DB bekommt!
INSERT INTO foo (col) VALUES('1 Hello
World')
INSERT INTO foo (col) VALUES('2 Hello\nWorld')
INSERT INTO foo (col) VALUES('3 Hello\
World')
INSERT INTO foo (col) VALUES('4 Hello\\nWorld')
INSERT INTO foo (col) VALUES('5 Hello\\
World')
INSERT INTO foo (col) VALUES('6 Hello\\\nWorld')
INSERT INTO foo (col) VALUES('7 Hello\\\
World')
INSERT INTO foo (col) VALUES('8 Hello\\\\nWorld')
Das Ergebnis in HeidiSQL war (<lf> steht für echten Linefeed):
1 Hello<lf>World
2 Hello<lf>World
3 Hello<lf>World
4 Hello\nWorld
5 Hello\<lf>World
6 Hello\<lf>World
7 Hello\<lf>World
8 Hello\\nWorld
Offensichtlich ist für MariaDB (und vermutlich auch MYSQL) die Sequenz \n und \<lf> gleichwertig und wird zu einem Linefeed umgewandelt. Und ein unescaptes <lf> wird ebenfalls akzeptiert.
Mit einem Prepared Statement geht es besser:
$stmt = $c->prepare("INSERT INTO foo (col) VALUES(?)");
$stmt->bind_param("s", $name);
$name = "1 Hello\nWorld"; $stmt->execute();
$name = "2 Hello\\nWorld"; $stmt->execute();
$name = "3 Hello\\\nWorld"; $stmt->execute();
$name = "4 Hello\\\\nWorld"; $stmt->execute();
Hier ist das Ergebnis weniger kopfzerbrechend, weil nur noch PHP das \ Zeichen auflöst:
1 Hello<lf>World
2 Hello\nWorld
3 Hello\<lf>World
4 Hello\\nWorld
Nun die Abfrage.
$result = $db->query("SELECT col FROM foo");
while ($row = $result->fetch_assoc()) {
echo "'$row[col]'\n";
}
ergibt
'1 Hello
World'
'2 Hello\nWorld'
'3 Hello\
World'
'4 Hello\\nWorld'
FAZIT
Ich kann Linefeeds in die SQL Datenbank schreiben und bekomme sie auch von PHP als Linefeeds zurück. Ohne Prepared Statements ist das aber eine Angelegenheit, bei der man jederzeit einige Zehen verlieren kann (weil man sich in den Fuß geschossen hat).
Rolf
--
sumpsi - posui - obstruxi