DOMDocument::loadHTML
除非您另有说明,否则会将您的字符串视为 ISO-8859-1(HTTP/1.1 默认字符集)。这会导致 UTF-8 字符串被错误解释。
DOMDocument 使用 HTML4 解析器。如果您正在加载 HTML5,您可能需要查看替代解决方案 https://stackoverflow.com/questions/10712503/how-to-make-html5-work-with-domdocument.
如果您正在处理 (X)HTML 的简单片段,则可以在前面添加 XML 编码声明或元字符集声明,以使字符串被视为 UTF-8:
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>';
$dom = new DOMDocument();
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $profile);
echo $dom->saveHTML();
$dom->loadHTML('<meta charset="utf8">' . $profile);
echo $dom->saveHTML();
// The above versions will HTML-encode high-ASCII bytes.
// This version preserves the original characters
$contentType = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
$dom->loadHTML($contentType . $profile);
echo $dom->saveHTML();
如果您无法知道 HTML 是否已包含声明,可以使用以下解决方法智能DOM文档 http://beerpla.net/projects/smartdomdocument-a-smarter-php-domdocument-class/这应该可以帮助你:
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>';
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8'));
echo $dom->saveHTML();
在 PHP 8.2+ 中,您将收到弃用警告,因此替代方案是:
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>';
$dom = new DOMDocument();
$dom->loadHTML(mb_encode_numericentity($profile, [0x80, 0x10FFFF, 0, ~0], 'UTF-8'));
echo $dom->saveHTML();
(为了更好地解释这个相当神秘的数组,请参阅here https://stackoverflow.com/questions/35854535/better-explanation-of-convmap-in-mb-encode-numericentity.)
这不是一个很好的解决方法,但由于并非所有字符都可以用 ISO-8859-1 表示(例如这些武士刀),因此它是最安全的替代方案。