我通过PHP echos发送一个XML文档来响应 AJAX 调用。为了形成这个XML文档,我遍历了一个数据库的记录。问题是数据库中包含有“〈”符号的记录。所以很自然地,浏览器在那个特定的位置抛出了一个错误。如何修复这个错误?
uidvcgyl1#
从PHP 5.4开始,您可以用途:
htmlspecialchars($string, ENT_XML1);
您应该指定编码,例如:
htmlspecialchars($string, ENT_XML1, 'UTF-8');
请注意,以上只会转换:
&
&
<
<
>
>
如果要对用双引号括起来的属性中使用的文本进行转义:
htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8');
除了&、<和>之外,还将"转换为"。如果属性用单引号括起来:
"
"
htmlspecialchars($string, ENT_XML1 | ENT_QUOTES, 'UTF-8');
除了将&、<、>和"转换为'之外,还将'转换为'。(Of当然,您甚至可以在属性之外使用它)。请参阅the manual entry for htmlspecialchars。
'
'
oyt4ldly2#
通过使用htmlspecialchars对这些字符进行转义,或者更恰当地说,使用用于构建XML文档的库(如DOMDocument或XMLWriter)。另一种替代方法是使用CDATA节,但这样就必须注意]]>的出现。还要考虑到,您必须遵守为XML文档定义的编码(默认情况下为UTF-8)。
htmlspecialchars
]]>
xpszyzbs3#
1)您可以将文本换行为CDATA,如下所示:
<mytag> <![CDATA[Your text goes here. Btw: 5<6 and 6>5]]> </mytag>
请参阅http://www.w3schools.com/xml/xml_cdata.asp2)好像已经有人说:转义那些字符。例如,如下所示:
5<6 and 6>5
nnt7mjpx4#
试试看:
$str = htmlentities($str,ENT_QUOTES,'UTF-8');
因此,在使用htmlentities()函数过滤数据后,可以使用XML标记中的数据,如下所示:
htmlentities()
<mytag>$str</mytag>
goqiplq25#
如果可能的话,使用XML类而不是字符串操作来创建XML总是一个好主意-好处之一是类将根据需要自动转义字符。
li9yvcax6#
加上这个以防对别人有帮助。由于我正在处理日语字符,编码也设置得很合适。但是,我不时地发现htmlentities和htmlspecialchars是不够的。一些用户输入包含特殊字符,这些字符不能被上述函数去除。在这些情况下,我必须这样做:
htmlentities
preg_replace('/[\x00-\x1f]/','',htmlspecialchars($string))
这也会移除某些xml-unsafe控制字符,例如Null character或EOT。您可以使用此table来决定要省略哪些字符。
xml-unsafe
Null character
EOT
k10s72fa7#
我更喜欢Golang对XML进行引号转义的方式(以及一些额外的功能,如换行符转义和其他字符转义),因此我将其XML转义函数移植到了下面的PHP
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; }
注意,由于mb_ord的使用,你至少需要PHP7.2,或者你必须用另一个polyfill来替换它,但是这些函数对我们来说工作得很好!对于任何好奇的人,这里是相关的围棋资源https://golang.org/src/encoding/xml/xml.go?s=44219:44263#L1887
mb_ord
7条答案
按热度按时间uidvcgyl1#
从PHP 5.4开始,您可以用途:
您应该指定编码,例如:
更新
请注意,以上只会转换:
&
至&
<
至<
>
至>
如果要对用双引号括起来的属性中使用的文本进行转义:
除了
&
、<
和>
之外,还将"
转换为"
。如果属性用单引号括起来:
除了将
&
、<
、>
和"
转换为'
之外,还将'
转换为'
。(Of当然,您甚至可以在属性之外使用它)。
请参阅the manual entry for htmlspecialchars。
oyt4ldly2#
通过使用
htmlspecialchars
对这些字符进行转义,或者更恰当地说,使用用于构建XML文档的库(如DOMDocument或XMLWriter)。另一种替代方法是使用CDATA节,但这样就必须注意
]]>
的出现。还要考虑到,您必须遵守为XML文档定义的编码(默认情况下为UTF-8)。
xpszyzbs3#
1)您可以将文本换行为CDATA,如下所示:
请参阅http://www.w3schools.com/xml/xml_cdata.asp
2)好像已经有人说:转义那些字符。例如,如下所示:
nnt7mjpx4#
试试看:
因此,在使用
htmlentities()
函数过滤数据后,可以使用XML标记中的数据,如下所示:goqiplq25#
如果可能的话,使用XML类而不是字符串操作来创建XML总是一个好主意-好处之一是类将根据需要自动转义字符。
li9yvcax6#
加上这个以防对别人有帮助。
由于我正在处理日语字符,编码也设置得很合适。但是,我不时地发现
htmlentities
和htmlspecialchars
是不够的。一些用户输入包含特殊字符,这些字符不能被上述函数去除。在这些情况下,我必须这样做:
这也会移除某些
xml-unsafe
控制字符,例如Null character
或EOT
。您可以使用此table来决定要省略哪些字符。k10s72fa7#
我更喜欢Golang对XML进行引号转义的方式(以及一些额外的功能,如换行符转义和其他字符转义),因此我将其XML转义函数移植到了下面的PHP
注意,由于
mb_ord
的使用,你至少需要PHP7.2,或者你必须用另一个polyfill来替换它,但是这些函数对我们来说工作得很好!对于任何好奇的人,这里是相关的围棋资源https://golang.org/src/encoding/xml/xml.go?s=44219:44263#L1887