Ich antworte auf einen AJAX - Aufruf, indem ich ein XML-Dokument über PHP -Echos sende. Um dieses XML-Dokument zu erstellen, durchlaufe ich die Datensätze einer Datenbank. Das Problem ist, dass die Datenbank Datensätze enthält, die '<' Symbole enthalten. Natürlich wirft der Browser an dieser Stelle einen Fehler ab. Wie kann das behoben werden?
Indem Sie diese Zeichen entweder mit htmlspecialchars
umgehen, oder, besser geeignet, eine Bibliothek zum Erstellen von XML-Dokumenten verwenden, z. B. DOMDocument oder XMLWriter .
Eine andere Alternative wäre die Verwendung von CDATA-Abschnitten, aber dann müsste nach Vorkommen von ]]>
gesucht werden.
Berücksichtigen Sie auch, dass Sie die für das XML-Dokument definierte Kodierung einhalten müssen (standardmäßig UTF-8).
Seit PHP 5.4 können Sie Folgendes verwenden:
htmlspecialchars($string, ENT_XML1);
Sie sollten die Kodierung wie folgt angeben:
htmlspecialchars($string, ENT_XML1, 'UTF-8');
Beachten Sie, dass das Obige nur konvertiert:
&
bis &
<
bis <
>
bis >
Wenn Sie Text für die Verwendung in einem Attribut in doppelte Anführungszeichen setzen möchten:
htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8');
konvertiert "
in "
zusätzlich zu &
, <
und >
.
Und wenn Ihre Attribute in einfachen Anführungszeichen stehen:
htmlspecialchars($string, ENT_XML1 | ENT_QUOTES, 'UTF-8');
konvertiert '
in '
zusätzlich zu &
, <
, >
und "
.
(Natürlich können Sie dies auch außerhalb von Attributen verwenden).
1) Sie können Ihren Text wie folgt als CDATA umbrechen:
<mytag>
<![CDATA[Your text goes here. Btw: 5<6 and 6>5]]>
</mytag>
siehe http://www.w3schools.com/xml/xml_cdata.asp
2) Wie schon jemand gesagt hat: Entkomme den Zeichen. Z.B. wie so:
5<6 and 6>5
Versuche dies:
$str = htmlentities($str,ENT_QUOTES,'UTF-8');
Nachdem Sie Ihre Daten mit der Funktion htmlentities()
gefiltert haben, können Sie die Daten im XML-Tag wie folgt verwenden:
<mytag>$str</mytag>
Wenn überhaupt möglich, ist es immer eine gute Idee, XML anhand der XML-Klassen zu erstellen, anstatt Zeichenfolgen zu ändern. Dies hat den Vorteil, dass die Klassen Zeichen bei Bedarf automatisch mit Escapezeichen versehen.
Dies hinzuzufügen, falls es jemandem hilft.
Da ich mit japanischen Zeichen arbeite, wurde auch die Kodierung entsprechend festgelegt. Ich finde jedoch von Zeit zu Zeit, dass htmlentities
und htmlspecialchars
nicht ausreichen.
Einige Benutzereingaben enthalten Sonderzeichen, die von den obigen Funktionen nicht entfernt werden. In diesen Fällen muss ich Folgendes tun:
preg_replace('/[\x00-\x1f]/','',htmlspecialchars($string))
Dadurch werden auch bestimmte xml-unsafe
Steuerzeichen wie Null character
oder EOT
entfernt. Mit dieser table können Sie bestimmen, welche Zeichen Sie weglassen möchten.
Ich bevorzuge die Art und Weise, wie Golang für XML Escapeing verwendet (und ein paar Extras wie Newline-Escape und andere Zeichen), also habe ich seine XML-Escape-Funktion nach PHP portiert
function isInCharacterRange(int $r): bool {
return $r == 0x09 ||
$r == 0x0A ||
$r == 0x0D ||
$r >= 0x20 && $r <= 0xDF77 ||
$r >= 0xE000 && $r <= 0xFFFD ||
$r >= 0x10000 && $r <= 0x10FFFF;
}
function xml(string $s, bool $escapeNewline = true): string {
$w = '';
$Last = 0;
$l = strlen($s);
$i = 0;
while ($i < $l) {
$r = mb_substr(substr($s, $i), 0, 1);
$Width = strlen($r);
$i += $Width;
switch ($r) {
case '"':
$esc = '"';
break;
case "'":
$esc = ''';
break;
case '&':
$esc = '&';
break;
case '<':
$esc = '<';
break;
case '>':
$esc = '>';
break;
case "\t":
$esc = '	';
break;
case "\n":
if (!$escapeNewline) {
continue 2;
}
$esc = '
';
break;
case "\r":
$esc = '
';
break;
default:
if (!isInCharacterRange(mb_ord($r)) || (mb_ord($r) === 0xFFFD && $Width === 1)) {
$esc = "\u{FFFD}";
break;
}
continue 2;
}
$w .= substr($s, $Last, $i - $Last - $Width) . $esc;
$Last = $i;
}
$w .= substr($s, $Last);
return $w;
}
Beachten Sie, dass Sie mindestens PHP7.2 benötigen, da mb_ord
verwendet wird, oder Sie müssen es gegen eine andere Polyfill austauschen. Diese Funktionen funktionieren jedoch hervorragend für uns!
Für Neugierige ist hier die relevante Go-Quelle https://golang.org/src/encoding/xml/xml.go?s=44219:44263#L1887