php 你如何使字符串“XML 安全”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3426090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:42:00  来源:igfitidea点击:

How do you make strings "XML safe"?

phpxmlcakephp

提问by JayD3e

I am responding to an AJAX call by sending it an XML document through PHP echos. In order to form this XML document, I loop through the records of a database. The problem is that the database includes records that have '<' symbols in them. So naturally, the browser throws an error at that particular spot. How can this be fixed?

我通过 PHP 回声向 AJAX 调用发送一个 XML 文档来响应它。为了形成这个 XML 文档,我遍历了一个数据库的记录。问题是数据库包含其中包含“<”符号的记录。很自然地,浏览器会在该特定位置抛出错误。如何解决这个问题?

回答by user3409662

Since PHP 5.4 you can use:

自 PHP 5.4 起,您可以使用:

htmlspecialchars($string, ENT_XML1);

You should specify the encoding, such as:

您应该指定编码,例如:

htmlspecialchars($string, ENT_XML1, 'UTF-8');


Update

更新

Note that the above will only convert:

请注意,以上只会转换:

  • &to &amp;
  • <to &lt;
  • >to &gt;
  • &&amp;
  • <&lt;
  • >&gt;


If you want to escape text for use in an attribute enclosed in double quotes:

如果要转义文本以在双引号括起来的属性中使用:

htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8');

will convert "to &quot;in addition to &, <and >.

将转换"&quot;除了&,<>



And if your attributes are enclosed in single quotes:

如果您的属性用单引号括起来:

htmlspecialchars($string, ENT_XML1 | ENT_QUOTES, 'UTF-8');

will convert 'to &apos;in addition to &, <, >and ".

除了、和之外,还将转换'为。&apos;&<>"

(Of course you can use this even outside of attributes).

(当然,您甚至可以在属性之外使用它)。



See the manual entry for htmlspecialchars.

请参阅htmlspecialchars 的手册条目

回答by Artefacto

By either escaping those characters with htmlspecialchars, or, perhaps more appropriately, using a library for building XML documents, such as DOMDocumentor XMLWriter.

通过使用 来转义这些字符htmlspecialchars,或者更恰当地使用用于构建 XML 文档的库,例如DOMDocumentXMLWriter

Another alternative would be to use CDATA sections, but then you'd have to look out for occurrences of ]]>.

另一种选择是使用 CDATA 部分,但是您必须注意]]>.

Take also into consideration that that you must respect the encoding you define for the XML document (by default UTF-8).

还要考虑到您必须遵守为 XML 文档定义的编码(默认情况下为 UTF-8)。

回答by Elvith

1) You can wrap your text as CDATA like this:

1)您可以像这样将文本包装为 CDATA:

<mytag>
    <![CDATA[Your text goes here. Btw: 5<6 and 6>5]]>
</mytag>

see http://www.w3schools.com/xml/xml_cdata.asp

http://www.w3schools.com/xml/xml_cdata.asp

2) As already someone said: Escape those chars. E.g. like so:

2)正如有人所说:转义这些字符。例如像这样:

5&lt;6 and 6&gt;5

回答by Mosiur

Try this:

尝试这个:

$str = htmlentities($str,ENT_QUOTES,'UTF-8');

So, after filtering your data using htmlentities()function, you can use the data in XML tag like:

因此,在使用htmlentities()函数过滤数据后,您可以使用 XML 标记中的数据,例如:

<mytag>$str</mytag>

回答by Ed Schembor

If at all possible, its always a good idea to create your XML using the XML classes rather than string manipulation - one of the benefits being that the classes will automatically escape characters as needed.

如果可能的话,使用 XML 类而不是字符串操作来创建 XML 总是一个好主意 - 好处之一是这些类会根据需要自动转义字符。

回答by Reuben L.

Adding this in case it helps someone.

添加这个以防它帮助某人。

As I am working with Japanese characters, encoding has also been set appropriately. However, from time to time, I find that htmlentitiesand htmlspecialcharsare not sufficient.

当我使用日语字符时,编码也已适当设置。然而,我时不时地发现这htmlentitieshtmlspecialchars不够。

Some user inputs contain special characters that are not stripped by the above functions. In those cases I have to do this:

某些用户输入包含未被上述函数剥离的特殊字符。在这些情况下,我必须这样做:

preg_replace('/[\x00-\x1f]/','',htmlspecialchars($string))

This will also remove certain xml-unsafecontrol characters like Null characteror EOT. You can use this tableto determine which characters you wish to omit.

这也将删除某些xml-unsafe控制字符,如Null characterEOT。您可以使用此来确定要省略哪些字符。

回答by Brian Leishman

I prefer the way Golang does quote escaping for XML (and a few extras like newline escaping, and escaping some other characters), so I have ported its XML escape function to PHP below

我更喜欢 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 = '&#34;';
                break;
            case "'":
                $esc = '&#39;';
                break;
            case '&':
                $esc = '&amp;';
                break;
            case '<':
                $esc = '&lt;';
                break;
            case '>':
                $esc = '&gt;';
                break;
            case "\t":
                $esc = '&#x9;';
                break;
            case "\n":
                if (!$escapeNewline) {
                    continue 2;
                }
                $esc = '&#xA;';
                break;
            case "\r":
                $esc = '&#xD;';
                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;
}

Note you'll need at least PHP7.2 because of the mb_ordusage, or you'll have to swap it out for another polyfill, but these functions are working great for us!

请注意,由于mb_ord使用原因,您至少需要 PHP7.2 ,否则您必须将其换成另一个 polyfill,但这些功能对我们来说非常有用!

For anyone curious, here is the relevant Go source https://golang.org/src/encoding/xml/xml.go?s=44219:44263#L1887

对于任何好奇的人,这里是相关的 Go 源https://golang.org/src/encoding/xml/xml.go?s=44219:44263#L1887