函数的
allowable_tags参数包含非法字符或格式不正确,可能导致输出为空。请确保
allowable_tags`参数正确设置。在001.54.及PHP5.5关于htmlspecialchars输出为空的问题
在PHP 5.4及更高版本中,htmlspecialchars
函数的行为发生了变化,这导致了一些编码问题,尤其是对于使用非UTF8编码的中文网站,本文将详细解释这一问题的原因及其解决方案,并附上相关FAQs。
以下是PHP 5.4及PHP 5.5关于htmlspecialchars输出为空的问题:
原因分析
从PHP 5.3升级到PHP 5.4后,htmlspecialchars
函数的默认编码参数值由ISO88591更改为了UTF8,这一变化导致在使用GBK或GB2312编码的中文网站时,htmlspecialchars
函数的输出结果为空,具体表现如下:
$str = "9enjoy.com的php版本是5.2.10"; echo htmlspecialchars($str); // GBK字符集下输出为空...utf8下,输出正常。
这是因为在PHP 5.4之前,如果省略了编码参数,则默认使用ISO88591编码,而在PHP 5.4及以后的版本中,省略编码参数会默认使用UTF8编码,当处理包含GBK或GB2312编码的字符串时,由于编码不匹配,导致输出为空。
解决方案
修改程序代码
1、修改所有用到htmlspecialchars
地方的程序
使用GB2312编码:
```php
echo htmlspecialchars($str, ENT_COMPAT, 'GB2312');
```
注意:PHP不支持GBK作为有效的编码参数,如果强行使用GBK,则会报错:
```plaintext
Warning: htmlspecialchars(): charset `gbk' not supported, assuming utf8
```
为了解决这个问题,可以使用ISO88591编码来代替GBK:
```php
echo htmlspecialchars($str, ENT_COMPAT, 'ISO88591');
```
使用空字符串激活检测机制:
可以在网页头部设置默认字符集为GBK,然后使用空字符串作为编码参数:
```php
ini_set('default_charset', 'gbk');
echo htmlspecialchars($str, ENT_COMPAT, '');
```
需要注意的是,这种方法并不推荐,因为它会依赖于脚本编码、默认字符集和当前区域设置的检测顺序。
2、封装函数:
为了简化替换过程,可以封装一个新的函数来替代htmlspecialchars
:
```php
function htmlout($str) {
return htmlspecialchars($str, ENT_COMPAT, 'ISO88591');
}
```
然后在代码中批量替换原有的htmlspecialchars
调用。
修改源码并重编译
1、直接修改PHP源码:
修改ext/standard/html.c
文件,将第372行左右的代码从:
```c
/* Default is now UTF8 */
if (charset_hint == NULL) return cs_utf_8;
```
改为:
```c
/* Default is now UTF8 */
if (charset_hint == NULL) return cs_8859_1;
```
然后重新编译PHP,这样原来的程序就不需要做任何调整。
表格对比
方法 | 优点 | 缺点 |
修改程序代码 | 简单易行,适用于大多数情况 | 需要修改大量代码,工作量大 |
使用GB2312编码 | 兼容性好,适合GB2312编码的网站 | 不支持GBK编码,需要用ISO88591替代 |
使用空字符串激活检测机制 | 无需修改每个htmlspecialchars 调用 | 不推荐,依赖于多种因素,可能导致不可预知的问题 |
封装函数 | 简化替换过程,提高代码可读性 | 需要额外维护封装函数 |
修改源码并重编译 | 一劳永逸,彻底解决问题 | 技术要求高,风险较大,需要重新编译PHP |
相关问答FAQs
Q1: 为什么在PHP 5.4及之后的版本中,htmlspecialchars
函数的默认编码参数值会从ISO88591更改为UTF8?
A1: 主要原因是国际标准化趋势,UTF8逐渐成为互联网上最常用的字符编码标准,PHP开发团队认为UTF8应该是默认的字符编码方式,以适应更多的国际化应用场景,这一改变对使用其他编码(如GBK、GB2312)的中文网站造成了影响。
Q2: 如何在不修改源码的情况下解决htmlspecialchars
输出为空的问题?
A2: 可以通过以下几种方法来解决:
1、使用GB2312编码:将htmlspecialchars
的第三个参数设置为GB2312
,如果遇到不支持GBK的情况,可以使用ISO88591
替代。
2、使用空字符串激活检测机制:在网页头部设置默认字符集为GBK,然后将htmlspecialchars
的第三个参数设置为空字符串,不过这种方法并不推荐,因为它依赖于多种因素,可能导致不可预知的问题。
3、封装函数:创建一个新函数来封装htmlspecialchars
,并将新的函数用于替换原有调用,这样可以简化代码的修改过程。
<?php // PHP5.4及PHP5.5中htmlspecialchars输出为空的问题分析及解决方案 /问题描述 * 在PHP5.4和PHP5.5版本中,使用htmlspecialchars()函数对字符串进行转义时,如果传入的字符串为空或者包含的字符已经被转义,则可能返回空字符串。原因分析 * 这种现象通常是由于PHP内部处理逻辑的变化引起的,在早期版本中,htmlspecialchars()函数会处理所有需要转义的字符,包括已经转义的字符,但在5.4和5.5版本中,如果字符串已经包含转义字符,则函数可能不会进行额外的转义。解决方案 */ // 示例代码 $originalString = 'Hello, & World!'; // 包含已经转义的字符 $escapedString = htmlspecialchars($originalString, ENT_QUOTES, 'UTF8'); // 输出结果可能为空 echo $escapedString; // 输出可能为空字符串 // 解决方案1:使用str_replace()手动转义 $fixedString = str_replace(array('&', '"', '<', '>', "'"), array('&', '"', '<', '>', '''), $originalString); echo htmlspecialchars($fixedString, ENT_QUOTES, 'UTF8'); // 应该正确输出转义后的字符串 // 解决方案2:使用htmlspecialchars()处理未转义的字符 $parts = preg_split('/(&[az]+;)/i', $originalString, null, PREG_SPLIT_DELIM_CAPTURE); foreach ($parts as $part) { if (strpos($part, '&') !== false && strpos($part, ';') !== false) { // 已经转义的字符,不处理 } else { // 未转义的字符,进行转义 $part = htmlspecialchars($part, ENT_QUOTES, 'UTF8'); } echo $part; } ?>
代码提供了两种解决方案来处理PHP5.4和PHP5.5中htmlspecialchars()
输出为空的问题,第一种是通过str_replace()
手动转义所有需要转义的字符,第二种是使用正则表达式来区分已经转义的字符和未转义的字符,只对未转义的字符进行转义处理。