脚本标记中的Symfony dom-crawler字符串转换为UTF8

时间:2016-04-09 17:48:05

标签: php symfony utf-8 domcrawler

我有这个HTML内容:

<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('测试');
    }
</script>

当我使用Symfony的dom-crawler时,文本正在进行HTML编码。我怎么能阻止这个? $crawler->html()结果:

<div>测试</div>
<script>
    function drawCharts(){
        console.log('&#27979;&#35797;');
    }

1 个答案:

答案 0 :(得分:2)

让我们看看symfony / dom-crawler是如何工作的。这是一个开头的例子:

<?php

require 'vendor/autoload.php';

use Symfony\Component\DomCrawler\Crawler;

$html = <<<HTML
<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('测试');
    }
</script>
HTML;

$crawler = new Crawler($html);

print $crawler->html();

输出:

<div>æµè¯</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('&aelig;&micro;&#139;&egrave;&macr;&#149;');
    }
</script>

当您通过constructorCrawlerdoes its best传递内容以确定编码时。如果它没有弄明白,那就falls back to ISO-8859-1;这是HTTP 1.1规范定义的默认字符集。

如果您的HTML内容包含charset meta tag,则Crawler类将从中读取字符集,并正确设置它并convert from it。以上是与HTML内容前面加上charset元标记相同的示例:

<?php

require 'vendor/autoload.php';

use Symfony\Component\DomCrawler\Crawler;

$html = <<<HTML
<meta charset="utf-8">
<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('测试');
    }
</script>
HTML;

$crawler = new Crawler($html);

print $crawler->html();

现在打印:

<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('&#27979;&#35797;');
    }
</script>

如果您不想添加charset元标记,还有另一种方法; addHTMLContent()方法接受charset作为其第二个参数,默认为UTF-8。不是通过构造函数传递HTML内容,而是首先实例化该类,然后使用此方法添加内容:

<?php

require 'vendor/autoload.php';

use Symfony\Component\DomCrawler\Crawler;

$html = <<<HTML
<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('测试');
    }
</script>
HTML;

$crawler = new Crawler;

// You can safely drop the 2nd argument
$crawler->addHTMLContent($html, 'UTF-8');     

print $crawler->html();

现在,没有charset元标记,它会打印:

<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('&#27979;&#35797;');
    }
</script>

好的,你可能已经知道了这一切。那么,&#27979;&#35797;是什么?为什么div内容按原样显示,但script标记中的相同内容是否采用html编码?

由于as it explains itself中的错误,Symfony的CrawlerDOMDocument::loadHTML()将内容转换为HTML实体:

  

使用loadHTML()处理UTF-8页面时,您可能会遇到DOM函数输出与输入不同的问题。例如,如果你想获得“Cạnhtranh”,你会收到“Cạnhtranh”。我建议我们在加载UTF-8页面之前使用mb_convert_encoding    - https://php.net/manual/en/domdocument.loadhtml.php#74777

有人建议在head元素中添加HTML4 Content-Type元标记。其他一些建议在将<?xml encoding="UTF-8">添加到HTML内容之前将其传递给loadHTML()。由于您的HTML结构不完整(缺少headbody等),我建议您只需将输出传递给html_entity_decode()

<?php

require 'vendor/autoload.php';

use Symfony\Component\DomCrawler\Crawler;

$html = <<<HTML
<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('测试');
    }
</script>
HTML;

$crawler = new Crawler();
$crawler->addHTMLContent($html, 'UTF-8');

print html_entity_decode($crawler->html());

输出:

<div>测试</div>
<script charset="utf-8" type="text/javascript">
    function drawCharts(){
        console.log('测试');
    }
</script>

这就是你想要的。

您可能还想阅读:
PHP DOMDocument loadHTML not encoding UTF-8 correctly