php htmlentities和htmlspecialchars 的区别


Posted in PHP onAugust 18, 2008

The translations performed are:

'&' (ampersand) becomes '&' 
'"' (double quote) becomes '"' when ENT_NOQUOTES is not set. 
''' (single quote) becomes ''' only when ENT_QUOTES is set. 
'<' (less than) becomes '<' 
'>' (greater than) becomes '>'

htmlspecialchars 只转化上面这几个html代码,而 htmlentities 却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。

我们可以拿一个简单的例子来做比较:

$str='<a href="test.html">测试页面</a>'; 
echo htmlentities($str); 
// <a href="test.html">²âÊÔÒ³Ãæ</a> $str='<a href="test.html">测试页面</a>'; 
echo htmlspecialchars($str); 
// <a href="test.html">测试页面</a>

结论是,有中文的时候,最好用 htmlspecialchars ,否则可能乱码

另外参考一下这个自定义函数

function my_excerpt( $html, $len ) { 
// $html 应包含一个 HTML 文档。 
// 本例将去掉 HTML 标记,javascript 代码 
// 和空白字符。还会将一些通用的 
// HTML 实体转换成相应的文本。 
$search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript 
"'<[\/\!]*?[^<>]*?>'si", // 去掉 HTML 标记 
"'([\r\n])[\s]+'", // 去掉空白字符 
"'&(quot|#34);'i", // 替换 HTML 实体 
"'&(amp|#38);'i", 
"'&(lt|#60);'i", 
"'&(gt|#62);'i", 
"'&(nbsp|#160);'i", 
"'&(iexcl|#161);'i", 
"'&(cent|#162);'i", 
"'&(pound|#163);'i", 
"'&(copy|#169);'i", 
"'&#(\d+);'e"); // 作为 PHP 代码运行 
$replace = array ("", 
"", 
"\\1", 
"\"", 
"&", 
"<", 
">", 
" ", 
chr(161), 
chr(162), 
chr(163), 
chr(169), 
"chr(\\1)"); 
$text = preg_replace ($search, $replace, $html); 
$text = trim($text); 
return mb_strlen($text) >= $len ? mb_substr($text, 0, $len) : ''; 
}

htmlspecialchar()函数和htmlentities()函数类似都是把html代码转换,htmlspecialchars_decode是把转化的html的编码转换成转换回来。

我们可以拿一个简单的例子来做比较:

$str='<a href="test.html">测试</a>'; 
$transstr = htmlspecialchars($str) ; 
echo $transstr . "<br />"; 
echo htmlspecialchars_decode($transstr)";

运行上面的代码,就可以看出两者的差别了。

一直都知道 PHP 中的 htmlentities 和 htmlspecialchars 函数都能把 html 中的特殊字符转换成对应的 character entity (不知道怎么翻译),也一直都知道 htmlentities 和 htmlspecialchars 函数有区别,但是一直都用不到这两个函数,也就没去研究过到底有什么区别。

今天用到了,懒得看 PHP 手册里的鸟语,觉得这种问题应该会有人用中文写过,于是 Google 关键词“htmlentities htmlspecialchars”,答案千篇一律。我已经司空见惯了,复制粘贴连小学生都会。经过对比发现,每篇文章大概都包含两部分:

第一部分是引用 PHP 手册的说明:

PHP 手册中对 htmlspecialchars 写道:

The translations performed are:

‘&' (ampersand) becomes ‘&' 
‘"' (double quote) becomes ‘"' when ENT_NOQUOTES is not set. 
”' (single quote) becomes ‘'' only when ENT_QUOTES is set. 
‘<' (less than) becomes ‘<' 
‘>' (greater than) becomes ‘>'

这部分无可厚非,但是第二部分的解释却并不怎么正确:

htmlspecialchars 只转化上面这几个html代码,而 htmlentities 却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。

我们可以拿一个简单的例子来做比较:

<?php 
$str='<a href="test.html">测试页面</a>'; 
echo htmlentities($str); // <a href="test.html">²âÊÔÒ³Ãæ</a> 
$str='<a href="test.html">测试页面</a>'; 
echo htmlspecialchars($str); 
// <a href="test.html">测试页面</a> 
?>

结论是,有中文的时候,最好用 htmlspecialchars ,否则可能乱码。

难道 htmlentities 函数只有一个参数吗?当然不是!htmlentities 还有三个可选参数,分别是 $quote_style、 $charset、 $double_encode,手册对 $charset 参数是这样描述的:

Defines character set used in conversion. The default character set is ISO-8859-1.

从上面程序输出的结果判断,$str 是 GB2312 编码的,“测试页面”几个字对应的十六进制值是:

B2 E2 CA D4 D2 B3 C3 E6

然而却被当成 ISO-8859-1 编码来解析:

²âÊÔÒ³Ãæ

正好对应 HTML character entity 里的:

²âÊÔÒ³Ãæ

当然会被 htmlentities 转义掉,但是只要加上正确的编码作为参数,根本就不会出现所谓的中文乱码问题:

$str='<a href="test.html">测试页面</a>';

echo htmlentities($str, ENT_COMPAT, 'gb2312');
// <a href="test.html">测试页面</a>三人成虎,以讹传讹。

结论:htmlentities 和 htmlspecialchars 的区别在于 htmlentities 会转化所有的 html character entity,而htmlspecialchars 只会转化手册上列出的几个 html character entity (也就是会影响 html 解析的那几个基本字符)。一般来说,使用 htmlspecialchars 转化掉基本字符就已经足够了,没有必要使用 htmlentities。实在要使用 htmlentities 时,要注意为第三个参数传递正确的编码。

PHP 相关文章推荐
解析php file_exists无效的解决办法
Jun 26 PHP
使用swoole扩展php websocket示例
Feb 13 PHP
php获取文件大小的方法
Feb 26 PHP
PHP加密解密类实例分析
Apr 20 PHP
php文件系统处理方法小结
May 23 PHP
php简单解析mysqli查询结果的方法(2种方法)
Jun 29 PHP
Ajax实现对静态页面的文章访问统计功能示例
Oct 10 PHP
php  PATH_SEPARATOR判断当前服务器系统类型实例
Oct 28 PHP
PHP经典设计模式之依赖注入定义与用法详解
May 21 PHP
php+laravel依赖注入知识点总结
Nov 04 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
Dec 31 PHP
PHP设计模式(观察者模式)
Jul 07 PHP
php magic_quotes_gpc的一点认识与分析
Aug 18 #PHP
php数组应用之比较两个时间的相减排序
Aug 18 #PHP
php中的数组操作函数整理
Aug 18 #PHP
PHP去除数组中重复的元素并按键名排序函数
Aug 18 #PHP
删除数组元素实用的PHP数组函数
Aug 18 #PHP
PHP 数组实例说明
Aug 18 #PHP
PHP获取网站域名和地址的代码
Aug 17 #PHP
You might like
PHP 如何向 MySQL 发送数据
2006/10/09 PHP
php对gzip文件或者字符串解压实例参考
2008/07/25 PHP
php结合安卓客户端实现查询交互实例
2015/05/05 PHP
10个值得深思的PHP面试题
2016/11/14 PHP
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
2012/07/31 Javascript
jquery 利用show和hidden实现级联菜单示例代码
2013/08/09 Javascript
js实现选中复选框文字变色的方法
2015/08/14 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之绑定事件
2015/11/19 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
2016/10/01 Javascript
JS控制FileUpload的上传文件类型实例代码
2016/10/07 Javascript
nodejs实现发出蜂鸣声音(系统报警声)的方法
2017/01/18 NodeJs
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
Node.js中.pfx后缀文件的处理方法
2017/03/10 Javascript
React Native基础入门之初步使用Flexbox布局
2018/07/02 Javascript
laydate时间日历插件使用方法详解
2018/11/14 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
2019/02/28 Javascript
vue中使用mxgraph的方法实例代码详解
2019/05/17 Javascript
vue递归获取父元素的元素实例
2020/08/07 Javascript
vue+elementUI实现简单日历功能
2020/09/24 Javascript
[01:00:26]Ti4主赛事胜者组第一天 EG vs NEWBEE 1
2014/07/19 DOTA
Python smallseg分词用法实例分析
2015/05/28 Python
Django 连接sql server数据库的方法
2018/06/30 Python
深入了解Python枚举类型的相关知识
2019/07/09 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
python 矢量数据转栅格数据代码实例
2019/09/30 Python
从多个tfrecord文件中无限读取文件的例子
2020/02/17 Python
python 截取XML中bndbox的坐标中的图像,另存为jpg的实例
2020/03/10 Python
用canvas显示验证码的实现
2020/04/10 HTML / CSS
会计学个人自荐信模板
2013/12/13 职场文书
建筑工程毕业生自我鉴定
2014/01/14 职场文书
文明礼貌演讲稿
2014/05/12 职场文书
2015年上半年党建工作总结
2015/03/30 职场文书
团委工作总结2015
2015/04/02 职场文书
汉语拼音教学反思
2016/02/22 职场文书
工作计划范文之财务管理
2019/08/09 职场文书
MySQL5.7并行复制原理及实现
2021/06/03 MySQL