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 相关文章推荐
为php4加入动态flash文件的生成的支持
Oct 09 PHP
php项目打包方法
Feb 18 PHP
Php注入点构造代码
Jun 14 PHP
利用php+mysql来做一个功能强大的在线计算器
Oct 12 PHP
PHP开发中常用的字符串操作函数
Feb 08 PHP
php的$_FILES的临时储存文件与回收机制实测过程
Jul 12 PHP
php顺序查找和二分查找示例
Mar 27 PHP
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
Oct 14 PHP
Yii 2中的load()和save()示例详解
Aug 03 PHP
关于laravel后台模板laravel-admin select框的使用详解
Oct 03 PHP
Laravel 将数据表的数据导出,并生成seeds种子文件的方法
Oct 09 PHP
详解Laravel制作API接口
May 31 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
ASP知识讲座四
2006/10/09 PHP
php计算两个整数的最大公约数常用算法小结
2015/03/05 PHP
JavaScript Event学习第五章 高级事件注册模型
2010/02/07 Javascript
用js来解决ajax读取页面乱码
2010/11/28 Javascript
Jquery中对数组的操作代码
2011/08/12 Javascript
根据json字符串生成Html的一种方式
2013/01/09 Javascript
js捕获鼠标滚轮事件代码
2013/12/16 Javascript
jquery队列queue与原生模仿其实现方法分享
2014/03/25 Javascript
使用jquery实现鼠标滑过弹出更多相关信息层附源码下载
2015/11/23 Javascript
3分钟快速搭建nodejs本地服务器方法运行测试html/js
2017/04/01 NodeJs
Vue之Watcher源码解析(1)
2017/07/19 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
vue中遇到的坑之变化检测问题(数组相关)
2017/10/13 Javascript
swiper插件自定义切换箭头按钮
2017/12/28 Javascript
ES6之模版字符串的具体使用
2018/05/17 Javascript
详解JavaScript中分解数字的三种方法
2021/01/05 Javascript
Python实现购物车程序
2018/04/16 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
在python中安装basemap的教程
2018/09/20 Python
pandas中apply和transform方法的性能比较及区别介绍
2018/10/30 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
Pycharm debug调试时带参数过程解析
2020/02/03 Python
TensorFLow 变量命名空间实例
2020/02/11 Python
django 实现手动存储文件到model的FileField
2020/03/30 Python
初中三好学生事迹材料
2014/01/13 职场文书
工厂保安员岗位职责
2014/01/31 职场文书
物理系毕业生自荐书
2014/06/13 职场文书
运动会标语
2014/06/21 职场文书
财务会计实训报告
2014/11/05 职场文书
助学金感谢信
2015/01/20 职场文书
应届生简历自我评价
2015/03/11 职场文书
辩论赛开场白大全(主持人+辩手)
2015/05/29 职场文书
2016年教师节感言
2015/12/09 职场文书
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
2021/05/26 Servers
Nginx反向代理至go-fastdfs案例讲解
2021/08/02 Servers
python自动化测试之Selenium详解
2022/03/13 Python