PHP使用临时DOMDocument获取innerHTML时字符转HTML实体如何解决
问题原因
临时创建的DOMDocument实例默认使用ISO-8859-1编码,未显式指定UTF-8编码时,会自动将多字节特殊字符转换为–、α这类HTML实体。
解决方法
方案1:显式指定临时DOMDocument的编码(推荐,适配PHP 5.4+)
创建DOMDocument后直接设置encoding属性,同时修正原代码中的变量名笔误(原代码中$t应为$temp):
function innerHTML(DOMNode $el){ $html = ''; foreach($el->childNodes as $node){ $temp = new DOMDocument(); // 显式指定编码为UTF-8 $temp->encoding = 'UTF-8'; $temp->appendChild($temp->importNode($node, true)); $html .= trim($temp->saveHTML()); } return (string)$html; }
方案2:预加载带编码声明的空HTML骨架(兼容更低版本PHP)
如果方案1不生效,可以先给临时DOM加载一段带UTF-8编码声明的空HTML,再导入目标节点:
function innerHTML(DOMNode $el){ $html = ''; foreach($el->childNodes as $node){ $temp = new DOMDocument(); // 加载带编码声明的空HTML,同时关闭无关的libxml警告 $temp->loadHTML('<?xml encoding="UTF-8"><html><body></body></html>', LIBXML_NOERROR | LIBXML_NOWARNING); // 将目标节点导入到body标签下 $temp->getElementsByTagName('body')->item(0)->appendChild($temp->importNode($node, true)); // 仅提取body内的内容拼接 $body = $temp->getElementsByTagName('body')->item(0); foreach ($body->childNodes as $child) { $html .= trim($temp->saveHTML($child)); } } return (string)$html; }
方案3:输出后统一反转义实体
如果以上方案都不符合你的场景,可以在最终返回结果前用html_entity_decode将实体转回原字符:
function innerHTML(DOMNode $el){ $html = ''; foreach($el->childNodes as $node){ $temp = new DOMDocument(); $temp->appendChild($temp->importNode($node,true)); $html .= trim($temp->saveHTML()); } // 按HTML5标准反转义所有实体,编码指定为UTF-8 return html_entity_decode($html, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8'); }
内容的提问来源于stack exchange,提问作者Googlebot
相关产品推荐
相关产品推荐

