DOMDocument编码问题/字符转换

Kyr*_*mia 7 php utf-8 domdocument

我正在使用DOMDocument来操作/修改HTML,然后才能输出到页面.这只是一个html片段,而不是一个完整的页面.我最初的问题是所有的法国人都搞砸了,经过一番试错后我才能纠正.现在,似乎只有一个问题仍然存在:'角色变成了?.

代码 :

<?php
    $dom = new DOMDocument('1.0','utf-8');
         $dom->loadHTML(utf8_decode($row->text));

         //Some pretty basic modification here, not even related to text

         //reinsert HTML, and make sure to remove DOCTYPE, html and body that get added auto.
         $row->text = utf8_encode(preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML())));
?>
Run Code Online (Sandbox Code Playgroud)

我知道utf8解码/编码会变得混乱,但这是迄今为止我能使它工作的唯一方法.这是一个示例字符串:

输入:Sans doute parce qu'il vient d'atteind datedéterminantedansson spectaculaire cheminement

产量:Sans doute parce qu?il vient d?atteindddddédédédanananandans son spectaculaire cheminement

如果我找到更多细节,我会添加它们.感谢您的时间和支持!

Art*_*cto 16

不要用utf8_decode.如果您的文本是UTF-8,请将其传递给它.

不幸的是,DOMDocument在HTML的情况下默认为LATIN1.看来行为就是这样

  • 如果提取远程文档,它应该从标题中推断出编码
  • 如果未发送标头或文件是本地的,请查找对应的meta-equiv
  • 否则,默认为LATIN1.

工作示例:

<?php
$s = <<<HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
Sans doute parce qu’il vient d’atteindre une date déterminante
dans son spectaculaire cheminement
</body>
</html>
HTML;

libxml_use_internal_errors(true);
$d = new domdocument;
$d->loadHTML($s);

echo $d->textContent;
Run Code Online (Sandbox Code Playgroud)

使用XML(默认为UTF-8):

<?php
$s = '<x>Sans doute parce qu’il vient d’atteindre une date déterminante'.
    'dans son spectaculaire cheminement</x>';
libxml_use_internal_errors(true);
$d = new domdocument;
$d->loadXML($s);

echo $d->textContent;
Run Code Online (Sandbox Code Playgroud)

  • 如果我没记错,我认为我曾经做过以下hacky修复,以确保html设置为utf8,`$ d-> loadHTML('<?xml version ="1.0"encoding ="UTF-8"?>' .$ html);`无论如何,在解析无效的html时似乎总能恢复得很好 (5认同)
  • @JosFaber`utf8_decode`将把ISO-8859-1中不能表示的所有字符(几乎都是所有Unicode字符并包含```)转换成问号,这是引发问题的问题. (2认同)

小智 7

loadHtml() 并不总是识别Content-type HTTP-EQUIV元标记中指定的正确编码.

如果DomDocument('1.0', 'UTF-8')loadHTML('<?xml version="1.0" encoding="UTF-8"?>' . $html)hacks不能正常工作(PHP 5.3.13),试试这个:

使用正确的Content-type HTTP-EQUIV元标记<head>在开始<html>标记后面添加另一个部分.然后调用loadHtml(),然后删除额外的<head>标签.

// Ensure entire page is encoded in UTF-8
$encoding = mb_detect_encoding($body);
$body = $encoding ? @iconv($encoding, 'UTF-8', $body) : $body;

// Insert a head and meta tag immediately after the opening <html> to force UTF-8 encoding
$insertPoint = false;
if (preg_match("/<html.*?>/is", $body, $matches, PREG_OFFSET_CAPTURE)) {
    $insertPoint = mb_strlen( $matches[0][0] ) + $matches[0][1];
}
if ($insertPoint) {
    $body = mb_substr(
        $body,
        0,
        $insertPoint
    ) . "<head><meta http-equiv='Content-type' content='text/html; charset=UTF-8' /></head>" . mb_substr(
        $body,
        $insertPoint
    );
}
$dom = new DOMDocument();

// Suppress warnings for loading non-standard html pages
libxml_use_internal_errors(true);
$dom->loadHTML($body);
libxml_use_internal_errors(false);

// Now remove extra <head>
Run Code Online (Sandbox Code Playgroud)

请参阅此文章:http://devzone.zend.com/1538/php-dom-xml-extension-encoding-processing/