解析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 相关文章推荐
从一个不错的留言本弄的mysql数据库操作类
Sep 02 PHP
PHP5中新增stdClass 内部保留类
Jun 13 PHP
php处理斐波那契数列非递归方法
Feb 04 PHP
ajax在joomla中的原生态应用代码
Jul 19 PHP
php并发对MYSQL造成压力的解决方法
Feb 21 PHP
PHP安装memcached扩展笔记
May 28 PHP
php文件读取方法实例分析
Jun 20 PHP
php类中的$this,static,final,const,self这几个关键字使用方法
Dec 14 PHP
深入讲解PHP的Yii框架中的属性(Property)
Mar 18 PHP
PHP实现微信JS-SDK接口选择相册及拍照并上传的方法
Dec 05 PHP
PHP使用strrev翻转中文乱码问题的解决方法
Jan 13 PHP
如何在PHP中生成随机数
Jun 04 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
基于PHPExcel的常用方法总结
2013/06/13 PHP
Nginx服务器上安装并配置PHPMyAdmin的教程
2015/08/18 PHP
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
jQuery powerFloat万能浮动层下拉层插件使用介绍
2010/12/27 Javascript
最佳JS代码编写的14条技巧
2011/01/09 Javascript
基于jquery的cookie的用法
2011/01/10 Javascript
将input file的选择的文件清空的两种解决方案
2013/10/21 Javascript
$.each与$().each的区别示例介绍
2014/03/20 Javascript
简介JavaScript中Math.cos()余弦方法的使用
2015/06/15 Javascript
简述JavaScript的正则表达式中test()方法的使用
2015/06/16 Javascript
详解JavaScript正则表达式之分组匹配及反向引用
2016/03/09 Javascript
jquery.cookie.js实现用户登录保存密码功能的方法
2016/04/15 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
原生Aajax 和jQuery Ajax 写法个人总结
2017/03/24 jQuery
微信小程序 动画的简单实例
2017/10/12 Javascript
JS获取数组中出现次数最多及第二多元素的方法
2017/10/27 Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
2017/11/15 Javascript
Vue实现鼠标经过文字显示悬浮框效果的示例代码
2020/10/14 Javascript
下载给定网页上图片的方法
2014/02/18 Python
python读取json文件并将数据插入到mongodb的方法
2015/03/23 Python
python 捕获shell脚本的输出结果实例
2017/01/04 Python
Tornado协程在python2.7如何返回值(实现方法)
2017/06/22 Python
Python3实现发送QQ邮件功能(文本)
2017/12/15 Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
2018/12/15 Python
Python +Selenium解决图片验证码登录或注册问题(推荐)
2020/02/09 Python
通过案例解析python鸭子类型相关原理
2020/10/10 Python
css3弹性盒模型(Flexbox)详细介绍
2014/10/08 HTML / CSS
CSS3实现10种Loading效果
2016/07/11 HTML / CSS
SHEIN香港:价格实惠的女性时尚服装
2018/08/14 全球购物
神路信息Java面试题目
2013/03/31 面试题
人力资源管理专业毕业生推荐信
2013/11/07 职场文书
夏季奶茶店创业计划书
2014/01/16 职场文书
开办大学饮食联盟创业计划书
2014/01/29 职场文书
经理聘任证明
2015/03/02 职场文书
2016春季运动会开幕词
2016/03/04 职场文书