【问题标题】:PHP's domdocument inserts  symbolPHP domdocument 插入符号
【发布时间】: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>

【问题讨论】:

    标签: php html dom domdocument


    【解决方案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 引起的。请注意,空格被视为一个字符。

    有三种解决方案:

    1. 确保输入为 UTF-8,
    2. 将服务器的字符集设置为 iso-8859-1
    3. 将所有字符正确转换为 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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-03
          • 2020-02-19
          • 2012-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-16
          相关资源
          最近更新 更多