圣詹姆斯公园
  • Introduction
  • 算法
    • RSA算法原理
    • 小议分解质因数函数的实现
  • 开发
    • OTP简介
    • PHP命令行下的信号处理
    • 将普通字符转换为HTML转义字符
    • 如何在微信或给到APP中打开点评APP
    • 开源许可证教程
    • 线上环境关于时间查询的一个坑
    • Git
      • Git的4个阶段的撤销更改
      • Git实用配置笔记
      • Git忽略提交.gitignore
    • SugarCRM
      • SugarCRM6.5中字段定制显示方法研究
      • SugarCRM6.5支持使用Elasticsearch记录日志
      • SugarCRM6.5数据查询方法研究
  • 运维
    • shell终端输出内容美化
    • tcpdump使用简介
    • Wikitten的Nginx配置拾遗
    • 在Docker Terminal中运行容器中的PHPUnit
Powered by GitBook
On this page
  • 引言
  • 正文
  • 方法一
  • 方法二
  • 方法三
  • mb_encode_numericentity
  1. 开发

将普通字符转换为HTML转义字符

作者:James Zhu (fatindeed@hotmail.com)

创建日期:2018-03-22

引言

这个问题来源于线上反馈的一个问题,类似AABC-EFGH-IJKL-MNOP的卡密,在某些手机上会显示为ĀBC-EFGH-IJKL-MNOP。目前尚未得知具体重现的场景,但根据经验,考虑将卡密显示转换为HTML转义字符,如将A转为A,应该可以避免这个问题。

正文

查阅PHP手册,我们发现 htmlentities() 和 htmlspecialchars() 可以对特殊字符进行转义,但普通字符(A-Z/0-9)仍然保持原样。那么如何将普通字符转换为HTML转义字符呢?

方法一

根据ASCII码输出,代码如下:

$str = 'AABC-EFGH-IJKL-MNOP';
for($i=0; $i < strlen($str); $i++) { 
    echo '&#'.ord($str[$i]).';';
}

方法二

有没有其它更简洁的方法呢?答案当然是有的,可以使用 preg_replace(),代码如下:

$str = 'AABC-EFGH-IJKL-MNOP';
echo preg_replace('/(.)/e', '"&#".ord("$1").";"', $str);

方法三

但是,不管在哪里,使用eval始终是不推荐的,可能存在被黑客攻击的漏洞。还有没有其它方法呢?还是有的,可以使用 mb_encode_numericentity(),代码如下:

$str = 'AABC-EFGH-IJKL-MNOP';
echo mb_encode_numericentity($str, array(0x20, 0x7E, 0, 0xFF));

mb_encode_numericentity

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

mb_encode_numericentity — Encode character to HTML numeric string reference

string mb_encode_numericentity( string $str , array $convmap [, string $encoding = mb_internal_encoding() [, bool $is_hex = FALSE ]] )

其它参数就不赘述了,这里主要说一下第2个参数$convmap,手册里有一段对于$convmap的示例:

$convmap = array (
 int start_code1, int end_code1, int offset1, int mask1,
 int start_code2, int end_code2, int offset2, int mask2,
 ........
 int start_codeN, int end_codeN, int offsetN, int maskN );
// Specify Unicode value for start_codeN and end_codeN
// Add offsetN to value and take bit-wise 'AND' with maskN, then
// it converts value to numeric string reference.

$convmap必须以4个元素一组的形式出现,4个参数含义如下:

  • start_code: The map affects items starting from this character code.

  • end_code: The map affects items up to this character code.

  • offset: Add a specific offset amount (positive or negative) for this character code.

  • mask: Value to be used for mask operation (character code bitwise AND mask value).

前2个元素比较好理解,就是要进行转义的范围。后2个参数我感觉是用来进行输出混淆,避免某些场景下明文输出。例如:

$str = 'AABC-EFGH-IJKL-MNOP';
echo mb_encode_numericentity($str, array(0x20, 0x7E, 7, 0xFF));

以上代码运行会后输出HHIJ4LMNO4PQRS4TUVW,即所有字符的ASCII码加7后输出的内容,这种混淆是可逆的。

最后个mask参数是对待转义的字符与mask进行AND的位运算,例如:

$str = 'AABC-EFGH-IJKL-MNOP';
echo mb_encode_numericentity($str, array(0x20, 0x7E, 0, 0xEE));

以上代码运行会后输出@@BB,DFFH,HJJL,LNN@,这种混淆是不可逆的,上例中的B/C都输出了B、F/G都输出了F。

以上就是mb_encode_numericentity()这个方法的简单说明,本文只起抛砖引玉的作用,实际应用中如何使用,大家自由发挥吧。

PreviousPHP命令行下的信号处理Next如何在微信或给到APP中打开点评APP

Last updated 6 years ago