PHP domdocument 插入符号

Posted

技术标签:

【中文标题】PHP domdocument 插入符号【英文标题】:PHP's domdocument inserts  symbol 【发布时间】:2015-04-23 05:59:04 【问题描述】:

给定一些 html,我将 http://php.net/manual/en/class.domdocument.php 类应用到它,保存它,并且偶尔会插入  符号。它似乎发生在具有单个空格(与 &amp;nbsp; 相对)的标签上,但似乎不是绝对的(只有第一个 &lt;span&gt; 元素表现出这种现象)。我尝试按照PHP DOMDocument->getElementByID adding  in place of empty <span> 的建议在显示生成的 HTML 时添加编码,但是问题仍然存在。是什么原因造成的,如何预防?

如果您对我这样做的原因感兴趣。我有一个应用程序,我用文本替换 HTML 图像。在将 HTML 从 Outlook 电子邮件复制并粘贴到 TinyMCE 编辑器,然后解析 HTML 时,我遇到了这种行为。

<?php
$message = <<<EOT
<p>Start</p>
<p> </p>
<p> </p>
<p></p>
<p class="MsoNormal">
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
<span style="font-size:10pt;font-family:Arial, 'sans-serif';color:#000080;">Phone: (444) 777-7777</span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
</p>
<p>End</p>
EOT;
    echo('<p>Initial HTML:</p> '.$message);
    $message_encoded = utf8_encode($message);
    $doc = new DOMDocument();
    $doc->loadHTML($message);
    $body = $doc->getElementsByTagName('body')->item(0);
    $message=$doc->saveHTML($body);
    echo('<p>Final HTML:</p> '.$message);
    echo('<p>Initial HTML encoded:</p> '.$message_encoded);
    $doc->loadHTML($message_encoded);
    $body = $doc->getElementsByTagName('body')->item(0);
    $message_encoded=$doc->saveHTML($body);
    echo('<p>Final HTML:</p> '.$message_encoded);
?>

输出:

<p>Initial HTML:</p> <p>Start</p>
<p> </p>
<p> </p>
<p></p>
<p class="MsoNormal">
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
<span style="font-size:10pt;font-family:Arial, 'sans-serif';color:#000080;">Phone: (444) 777-7777</span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
</p>
<p>End</p><p>Final HTML:</p> <body>
<p>Start</p>
<p>Â </p>
<p>Â </p>
<p></p>
<p class="MsoNormal">
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;">Â <br></span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br></span>
<span style="font-size:10pt;font-family:Arial, 'sans-serif';color:#000080;">Phone: (444)Â 777-7777</span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br></span>
</p>
<p>End</p>
</body><p>Initial HTML encoded:</p> <p>Start</p>
<p>Â </p>
<p>Â </p>
<p></p>
<p class="MsoNormal">
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;">Â <br /></span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
<span style="font-size:10pt;font-family:Arial, 'sans-serif';color:#000080;">Phone: (444)Â 777-7777</span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br /></span>
</p>
<p>End</p><p>Final HTML:</p> <body>
<p>Start</p>
<p>ÃÂ </p>
<p>ÃÂ </p>
<p></p>
<p class="MsoNormal">
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;">ÃÂ <br></span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br></span>
<span style="font-size:10pt;font-family:Arial, 'sans-serif';color:#000080;">Phone: (444)ÃÂ 777-7777</span>
<span style="font-size:10pt;font-family:Calibri, 'sans-serif';color:#000080;"> <br></span>
</p>
<p>End</p>
</body>

【问题讨论】:

【参考方案1】:

PHP DOM 扩展在utf8 中运行。类似的字节编码问题适用于 XML 文档。你当前的编码是ISO-8859-1吗?

根据http://php.net/manual/en/intro.dom.php 的建议:

DOM 扩展使用 UTF-8 编码。使用 utf8_encode() 和 utf8_decode() 处理 ISO-8859-1 编码的文本或使用 Iconv 处理其他编码。

尝试如下修改该部分:

<p>End</p>
EOT;
    $message = utf8_encode($message); // this should fix it.
    echo('<p>Initial HTML:</p> '.$message);

还将脚本输出设置为UTF8,并将文档保存在UTF8,以解决未来许多与编码相关的问题。

希望对您有所帮助。

【讨论】:

谢谢迪迪。这样做了,现在我得到了两个 Ã 而不是一个!请参阅修改后的原始帖子。查看phpinfo,看来我的系统配置不是utf8。具体来说,我将 exif 和 iconv 设置为 ISO-8859-15。也许是问题? 很可能是您的ISO 导致了问题。保存在ISO-8859-* 文本文档中的字符被发送到PHP 解释器。备份所有文件,然后尝试将它们全部转换为UTF8,有些字符可能会损坏,所以转换后检查文件。一旦PHP文档,所有输入和环境都在UTF8你应该不会遇到问题。【参考方案2】:

正如 DeDee 所说,您的问题是由 iso-8859-1 字符转换为 utf-8 引起的。请注意,空格被视为一个字符。

有三种解决方案:

    确保输入为 UTF-8, 将服务器的字符集设置为 iso-8859-1 将所有字符正确转换为 UTF-8。

我个人推荐1,不推荐2。

要完成 1)

确保使用文本编辑器(例如 Notepad++)来创建文件。 不要使用 Microsoft Word 等文本编辑器。这里的经验法则是确保您用于创建软件的任何编辑器都使用 UTF-8 编码。

要完成 2)

在***.htaccess 文件中:

AddDefaultCharset iso-8859-1

在您的 HTML 文件的 &lt;head&gt; 中:

<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">

完成 3)

这里有一段可以使用的代码:

//Convert character encoding to UTF-8
function replace_non_utf_characters($string) 
    /**
     * This array consists of $key=>$value pairs, where $key
     * is the character needing to be replaced, and $value is
     * the character $key is replaced by. Add characters to
     * this array as needed.
     */
    $replacement_array = array(
            chr(145) => "'", //the chr(#) are all Microsoft-encoded equivalents (e.g. open/close "smart" quotes)
            chr(146) => "'",
            chr(147) => "\"",
            chr(148) => "\"",
            chr(149) => "&#8226;",
            chr(150) => "&ndash;",
            chr(151) => "&mdash;",
            chr(153) => "&#8482;",
            chr(169) => "&copy;",
            chr(174) => "&reg;"
        );
    foreach($replacement_array as $key=>$replacement) 
        $string = str_replace($key, $replacement, $string);
    
    //Force UTF-8 encoding, so that there will always be an output
    return mb_convert_encoding(str_replace(chr(194), '', mb_convert_encoding($string, "UTF-8", 'HTML-ENTITIES')), 'HTML-ENTITIES');

【讨论】:

谢谢!我同意选项 2 不是最佳选择。我的困难是用户而不是我将内容输入到我的表单编辑器中,我无法控制他们是否从 Microsoft Word 中获取内容。我会研究选项 3。另外,也许有一些方法可以让 TinyMCE 进行这种转换。【参考方案3】:

如果您对我这样做的原因感兴趣。我有一个申请 我用文本替换 HTML 图像。当复制和 将 Outlook 电子邮件中的 HTML 粘贴到 TinyMCE 编辑器,然后 解析 HTML,我遇到了这种行为。

Microsoft Word 和 Outlook 在剪切粘贴到 TinyMCE 时会添加一堆垃圾。只需添加 TinyMCE 插件“粘贴”即可。仍然需要处理任何问题

【讨论】:

【参考方案4】:

尝试在$message_encoded = $doc-&gt;saveHTML($body); 之后添加$message_encoded = mb_convert_encoding($message_encoded , 'HTML-ENTITIES', 'UTF-8');

【讨论】:

这让我的情况变得更糟了。之前我只是偶尔添加一个 â ,但在“我是”之类的东西变成我之后 【参考方案5】:

这对我有用:

$htm = str_replace("&nbsp;"," ",$htm);
$doc->loadHTML($htm) ;

这是我摆脱 Â 符号的唯一方法。

【讨论】:

【参考方案6】:

这为我解决了问题:

$doc->loadHTML('<?xml encoding="utf-8"?>' . $message);

通过将字符串添加到您的 HTML 字符串中,您将告诉 PHP 使用 UTF-8 作为编码。

信用:https://gist.github.com/Xeoncross/9401853

【讨论】:

以上是关于PHP domdocument 插入符号的主要内容,如果未能解决你的问题,请参考以下文章

PHP DOMDocument loadHTML 错误

在 PHP 中使用 DOMDocument 缩进

PHP DOMDocument 添加了额外的标签

在 PHP 中从 DOMNode 创建 DOMDocument

PHP 4 中的新 DOMDocument()

PHP DOMDocument 丢失