解析php中的escape函数


Posted in PHP onJune 29, 2013

采用js对URL中的汉字进行escape编码。
<a href="" onclick="window.open('product_list.php?p_sort='+escape('三水点靠木'));">这样点击链接后的效时:
引用:http://127.0.0.1/shop/product_list.php?p_sort=PHP%u5F00%u53D1%u8D44%u6E90%u7F51
生成了这样的效果, 很明显用PHP的urldecode()或者base64_decode()是无法反解的。
解决方法, 用PHP写一个反解函数:

function js_unescape($str){        
$ret = '';        
$len = strlen($str);        
for ($i = 0; $i < $len; $i++)        
{                
if ($str[$i] == '%' && $str[$i+1] == 'u')                
{                        
$val = hexdec(substr($str, $i+2, 4));                        
if ($val < 0x7f) $ret .= chr($val);                        
else if($val < 0x800) $ret .= chr(0xc0|($val>>6)).chr(0x80|($val&0x3f));                        else $ret .= chr(0xe0|($val>>12)).chr(0x80|(($val>>6)&0x3f)).chr(0x80|($val&0x3f));                       
$i += 5;                
}                
else if ($str[$i] == '%')                
{                        
$ret .= urldecode(substr($str, $i, 3));                        
$i += 2;                
}                
else $ret .= $str[$i];        
}        
return $ret;}

注意JS编码会自动转换成为UTF-8, 所以必须进行编码转换才能得到正确的结果,否则会中文乱码。但如果使用UTF-8编码就不用这一步了。
代码如下:print iconv('utf-8', 'gb2312', js_unescape($_REQUEST['p_sort']));
到此我们就成功地反解了js的escape编码了。
如下:
另外我找到个用PHP实现js的escape编码的函数:
function phpescape($str)
{         
$sublen=strlen($str);
      $retrunString="";         
for ($i=0;$i<$sublen;$i++)         
{                  
if(ord($str[$i])>=127)                  
{                           
$tmpString=bin2hex(iconv("gb2312","ucs-2",substr($str,$i,2)));                           
//$tmpString=substr($tmpString,2,2).substr($tmpString,0,2);window下可能要打开此项                           
$retrunString.="%u".$tmpString;                           
$i++;                  
} else 
{                           
$retrunString.="%".dechex(ord($str[$i]));                  
}         
}         
return $retrunString;
}

在json中不支持中文,用它传送中文数据就会出现数据丢失或者乱码,必须在传 送前对要发送的字符串进行编码,由于传送过去需要用js进行数据解析,考虑到js中有unescape函数,故若在php中有个escape函数,对数据 进行编码,在客户端用unescape进行 解码,这样就会方便很多。
先在网上搜索一把,很多用php实现的escape函数,大同小异,比如下面一个:
function phpEscape($str) {
preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);
$ar = $r[0];
foreach($ar as $k=>$v) {
    if(ord($v[0]) < 128)
      $ar[$k] = rawurlencode($v);
    else
      $ar[$k] = "%u".bin2hex(iconv("GB2312","UCS-2",$v));
}
return join("",$ar);
}

这个函数可以很好的工作,但是,也许有新手不理解这个函数的原理(比如我),用起来总是不放心,现在我就来解释一下这个函数的原理。而且我认为,拿别人的代码来复用,好比站在了巨人的肩膀上,但是若不理解别人的代码,迟早要掉到地面上。
第一句:preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);这个是用正则表达式匹配 字符串中所有的字符,[\x80-\xff]. 匹配的是汉字,\x表示匹配字符的16进制编码,[ ] 是类选择符,“.” 表示任意一个字符,这样[\x80-\xff].匹配的是两个字符,其中第一个就是16进制从80到ff的字符,而这恰好就是汉字编码的第一个字符。这样 就能完整的匹配一个汉字。关于unicode中汉字的编码,大家可以到网上搜索一下。同理,[\x01-\x7f]+英文字符串,因为最早的英文是 ASCII编码,编码值小于128,也就是16进制的从01到7f,"+"表示一个或者多个字符,这样[\x01-\x7f]+就能匹配连续多个英文字符 串。
$ar = $r[0];             //$r[0]里存放是匹配到的数组
foreach($ar as $k=>$v) {
    if(ord($v[0]) < 128)                 //假如字符编码值小于128,说明是个英文字符
      $ar[$k] = rawurlencode($v);    //直接用rawurlencode编码
    else
      $ar[$k] = "%u".bin2hex(iconv("GB2312","UCS-2",$v));    //否则的话用iconv函数把汉字转变成ucs-2编码,也就是unicode编码
}

在javascript中就可以用unescape来解码了
\u0391-\uFFE5 和\u4e00-\u9fa5来匹配中文
但好像前者包含汉字下的A-¥等 后者可能是纯汉字。
其中解码函数为:
function unescape($str) {
         $str = rawurldecode($str);
         preg_match_all("/%u.{4}|&#x.{4};|&#\d+;|.+/U",$str,$r);
         $ar = $r[0];
         foreach($ar as $k=>$v) {
                  if(substr($v,0,2) == "%u")
                           $ar[$k] = iconv("UCS-2","GBK",pack("H4",substr($v,-4)));
                  elseif(substr($v,0,3) == "&#x")
                           $ar[$k] = iconv("UCS-2","GBK",pack("H4",substr($v,3,-1)));
                  elseif(substr($v,0,2) == "&#") {
                           $ar[$k] = iconv("UCS-2","GBK",pack("n",substr($v,2,-1)));
                  }
         }
         return join("",$ar);
}

一、编码范围
1. GBK (GB2312/GB18030)
\x00-\xff   GBK双字节编码范围
\x20-\x7f   ASCII
\xa1-\xff   中文
\x80-\xff   中文
2. UTF-8 (Unicode)
\u4e00-\u9fa5 (中文)
\x3130-\x318F (韩文
\xAC00-\xD7A3 (韩文)
\u0800-\u4e00 (日文)
ps: 韩文是大于[\u9fa5]的字符
正则例子:
preg_replace("/([\x80-\xff])/","",$str);
preg_replace("/([u4e00-u9fa5])/","",$str);
PHP 相关文章推荐
第十四节 命名空间 [14]
Oct 09 PHP
一个PHP+MSSQL分页的例子
Oct 09 PHP
phpfans留言版用到的数据操作类和分页类
Jan 04 PHP
利用PHP和AJAX创建RSS聚合器的代码
Mar 13 PHP
php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系
Nov 02 PHP
php教程 插件机制在PHP中实现方案
Nov 02 PHP
解析使用ThinkPHP应该掌握的调试手段
Jun 20 PHP
解析PHP可变函数的经典用法
Jun 20 PHP
php实现数组筛选奇数和偶数示例
Apr 11 PHP
PHP+jQuery+Ajax实现用户登录与退出
Apr 27 PHP
mac os快速切换多个PHP版本的方法
Mar 07 PHP
PHP getNamespaces()函数讲解
Feb 03 PHP
使用PHP会话(Session)实现用户登陆功能
Jun 29 #PHP
php获取数组中重复数据的两种方法
Jun 28 #PHP
php setcookie(name, value, expires, path, domain, secure) 参数详解
Jun 28 #PHP
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法
Jun 28 #PHP
使用PHP实现Mysql读写分离
Jun 28 #PHP
win7下memCache的安装过程(具体操作步骤)
Jun 28 #PHP
浅析memcache启动以及telnet命令详解
Jun 28 #PHP
You might like
php方法调用模式与函数调用模式简例
2011/09/20 PHP
php shell超强免杀、减少体积工具实现代码
2012/10/16 PHP
深入PHP5中的魔术方法详解
2013/06/17 PHP
推荐一款MAC OS X 下php集成开发环境mamp
2014/11/08 PHP
关于laravel 日志写入失败问题汇总
2019/10/17 PHP
js中function()使用方法
2013/12/24 Javascript
Node.js事件循环(Event Loop)和线程池详解
2015/01/28 Javascript
3个可以改善用户体验的AngularJS指令介绍
2015/06/18 Javascript
JS组件Bootstrap实现图片轮播效果
2016/05/16 Javascript
简单封装js的dom查询实例代码
2016/07/08 Javascript
Express之get,pos请求参数的获取
2017/05/02 Javascript
vue2.0s中eventBus实现兄弟组件通信的示例代码
2017/10/25 Javascript
vue2.x+webpack快速搭建前端项目框架详解
2017/11/30 Javascript
vue项目中v-model父子组件通信的实现详解
2017/12/10 Javascript
Vue引入jquery实现平滑滚动到指定位置
2018/05/09 jQuery
详解ES6 系列之异步处理实战
2018/10/26 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
解决webpack多页面内存溢出的方法示例
2019/10/08 Javascript
Python深入学习之装饰器
2014/08/31 Python
python操作ssh实现服务器日志下载的方法
2015/06/03 Python
windows下添加Python环境变量的方法汇总
2018/05/14 Python
Pycharm设置utf-8自动显示方法
2019/01/17 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
2020/07/23 Python
CSS3中利用animation属性创建雪花飘落特效
2014/05/14 HTML / CSS
Intersport西班牙:在线体育商店
2019/11/06 全球购物
斯洛伐克最大的婴儿食品和用品网上商店:Feedo.sk
2020/12/21 全球购物
如何打印出当前源文件的文件名以及源文件的当前行号
2015/04/05 面试题
珍珠鸟教学反思
2014/02/01 职场文书
大学生未来职业生涯规划书
2014/02/15 职场文书
优秀教师演讲稿
2014/05/06 职场文书
大学生万能检讨书范例
2014/10/04 职场文书
公安机关查摆剖析材料
2014/10/10 职场文书
怒海潜将观后感
2015/06/11 职场文书
2016寒假假期总结
2015/10/10 职场文书
Django给表单添加honeypot验证增加安全性
2021/05/06 Python
Python包argparse模块常用方法
2021/06/04 Python