文档章节

PHP_DOM处理中文乱码问题,DOMDocument->loadHTML()处理中文的一点问题

喵王不瞌睡
 喵王不瞌睡
发布于 2014/11/27 01:40
字数 1162
阅读 164
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

DOM是php比较新的xml和html处理类,可以像javascript那样方便的操作DOM树,网上更多的是介绍它处理XML的情况,今天我来介绍一个用它处理html时的中文问题,php版本为5.1.6,所有php代码均为utf8编码。

我要处理的html是使用curl从网页上读取过来的,一个是百度的首页,gb2312字符集,一个是有道的首页,utf8字符集,两者的html头部分分别如下:

<html><head><title>百度一下,你就知道   </title><meta http-equiv=Content-Type content="text/html;charset=gb2312">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="/pack23501M/index.css" type="text/css"/>
<script type="text/javascript" src="/pack23501M/all.js"></script>
<title>有道</title>

可以看出百度的代码非常不规范,而有道就好多了,这虽然是题外话,其实还是有些关系的,后面会提到。

以上两段html代码,用同样的方式处理结果却不同,比如下面简单的处理(输出网页的title):

$dom = new DOMDocument();
@$dom->loadHTML($html);
echo $dom->getElementsByTagName('title')->item(0)->nodeValue;
...
$html = $dom->saveHTML();

有道的输出结果是正常的,百度却是乱码:

ç™¾åº¦ä¸€ä¸‹ï¼Œä½ å°±çŸ¥é“

由于php文档的loadHTML上说了,DOM内部处理全部都是utf8的,所以除了传入内容要utf8化之外,传入的内容中最好还有声明字符集的html代码:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

注意,这就是DOM处理html和xml最大的不同了,xml一般要求在第一行就显示的声明字符集,而html则灵活得多,可声明可不声明。不过不管输出的内容是正常还是乱码,dom内的nodeValue和最终的输出结果都是一致的,说明dom工作正常,问题就在输入数据上。

于是,针对百度的gb2312网页内容,增加了两项处理,第一项是使用mb_convert_encoding把网页内容由gb2312编码转换为utf8编码,第二项是把html中的:

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

替换成了utf8的:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

这样按说应该是可以了,但百度的处理结果仍然是乱码,百思而不得其解,偶然当中发现如果$html的值是这样的话输出是正常的:

$html = mb_convert_encoding('<title>测试test</title>', 'gb2312', 'utf-8');
$html = '<meta http-equiv="Content-Type" content="text/html;charset=gb2312">' . $this->html;

这说明,DOM正确识别了html代码中的Content-Type描述,即使html是gb2312编码的,DOM也能夠自动转换为正确的代码。

现在的情况是这样的:

  • DOM工作正常
  • html已经转换为utf8编码
  • Content-Type描述也已经调整

怎么还是会出问题呢?先看看下面的Content-Type描述代码:

$meta = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';

看清楚喽,如果用$meta直接替换百度html代码中的那句meta,不会生效,仍然乱码;可如果把$meta添加到整个html代码前面,也就是<html>前面,输出就正常了,神奇吧。

于是我就推测,之前百度代码处理乱码的原因,可能是在它的html代码中,meta前面有个含有中文的<title>,DOM在解析到<title>的时候,遇到了非ascii字符,而这时没有解析到<meta>,DOM不知道整个html代码是什么字符集,也就无法正确判断<title>的编码,于是糊里糊涂的进行了错误的字符集转换。

为了证实我的猜测,试着这样处理一下:只修改<meta>,把定义位置放在<title>前面,把缺少的引号加上,但是字符集声明仍然为gb2312,html代码也不进行iconv转换,就像下面这样(注意为gb2312编码):

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>百度一下,你就知道   </title>

执行,输出正常,而且是正常的gb2312编码,没有乱码。所以我的猜测是正确的,关于Content-Type的meta声明一定要放在<title>前面才行。另外上例中如果把nodeValue输出,是utf8编码的,也就是DOM的内部使用编码,说明DOM输入和输出的时候都会进行字符集转换(根据html代码中的字符集声明)。

最后,总结一下,curl读过来的网页数据,全部iconv为utf8编码,然后把声明Content-Type的<meta>替换到紧跟在<head>的位置上,再用DOM处理就不会出现乱码了。

本文转载自:http://www.fwolf.com/blog/post/314

喵王不瞌睡
粉丝 11
博文 168
码字总数 51103
作品 0
浦东
个人站长
私信 提问
PHP DOMDocument保存xml时中文出现乱码

PHP DOMDocument保存xml时中文出现乱码 It event poll2016-09-18197 阅读 xml中文PHPDomDocument乱码 php中DOMDocument对于xml操作我们只要是英文是没有问题了,但如果是中文字体就会有乱码问...

It event poll
2016/09/18
0
0
Apache 中文乱码解决方案

Apache 中文乱码解决方案 服务器端: ====== 修改httpd.conf (在Redhat中放置的位置为/etc/httpd/conf/) 查找: AddDefaultCharset ISO-8859-1 改成: #AddDefaultCharset ISO-8859-1 AddDef......

鱼北子
2012/08/27
245
0
PHP json_encode() 函数详解及中文乱码问题

在 php 中使用 json_encode() 内置函数(php > 5.2)可以使用得 php 中数据可以与其它语言很好的传递并且使用它。 这个函数的功能是将数值转换成json数据存储格式。 ? 1 2 3 4 5 6 7 8 9 程序运...

zyt_1978
2016/06/19
100
0
Cocos2d-x初入学堂(17)-->打包成APK中文显示乱码

原作者:445822357 来源:博客网 欢迎转载!转载时请注明出处:http://write.blog.csdn.net/postedit/8363166 很久没有更新博客了,因为工作各种忙,忘能谅解.. 这个问题也是移植到android上...

智捷课堂
2015/09/10
76
1
echo json_encode() 输出中文不显示

PHP默认的jsonencode编码出来的是unicode编码的,也就是u的编码,用PHP的jsonencode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”u***”的格式。 虽然unicode编码可以在不同的页面...

ITCHN
2016/12/19
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

x005-构造程序逻辑

构造程序逻辑 结合生活例子运用程序语言 百钱百鸡是我国古代数学家张丘建在《算经》一书中提出的数学问题:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何...

伟大源于勇敢的开始
40分钟前
3
0
问题汇总

最近在补知识面的时候发现有几个问题, 第一个呢是 教程 没有提前准备好。(视频方面的吧 书上面的 都要有) 第二个呢是 ,开发工具太多了,搞不清楚到底用哪个了 和哪个教程相匹配。 第三个...

T型人才追梦者
今天
7
0
OSChina 周三乱弹 —— 我以前超喜欢晒太阳的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @watergood :分享海先生的单曲《东篱》: 《东篱》- 海先生 手机党少年们想听歌,请使劲儿戳(这里) @xiaoshiyue :早.先喝几大碗鸡汤 @小小...

小小编辑
今天
19
1
法国电力项目二期正式验收

2019年12月10日, 法国电力项目二期正式验收. 二期实现了一个个人能源的自交易/自管理APP + 管理后台。 并就未来的合作技术方向进行了探讨: 去中心化数据存储/搜索引擎 可信计算/零知识证明...

怎当她临去时秋波那一转
今天
13
0
索引延迟关联

前言 今天在看代码的时候学习到了一种索引的优化,就先在此记录下来。 具体 举个例子,原sql如下: SELECT * FROM TABLE WHERE INDEX = '' LIMIT 10000, 10; 现象 就算INDEX用了查询索引,...

无敌小杰杰
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部