解析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 相关文章推荐
打造计数器DIY三步曲(下)
Oct 09 PHP
随时给自己贴的图片加文字的php水印
Mar 16 PHP
php下防止单引号,双引号在接受页面转义的设置方法
Sep 25 PHP
最新的php 文件上传模型,支持多文件上传
Aug 13 PHP
PHP实现文件下载详解
Nov 27 PHP
ThinkPHP模版中导入CSS和JS文件的方法
Nov 29 PHP
php启用sphinx全文搜索的实现方法
Dec 24 PHP
php判断是否为ajax请求的方法
Nov 29 PHP
php 删除指定文件夹的实例讲解
Jul 25 PHP
PHP实现的Redis多库选择功能单例类
Jul 27 PHP
PHP使用SMTP邮件服务器发送邮件示例
Aug 28 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
Feb 27 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
ZF等常用php框架中存在的问题
2008/01/10 PHP
PHP spl_autoload_register实现自动加载研究
2011/12/06 PHP
php中使用key,value,current,next和prev函数遍历数组的方法
2015/03/17 PHP
zen cart实现订单中增加paypal中预留电话的方法
2016/07/12 PHP
Laravel中为什么不使用blpop取队列详析
2018/08/01 PHP
表单填写时用回车代替TAB的实现方法
2007/10/09 Javascript
jQuery 源码分析笔记(4) Ready函数
2011/06/02 Javascript
JavaScript与DOM组合动态创建表格实例
2012/12/23 Javascript
jquery.blockUI.js上传滚动等待效果实现思路及代码
2013/03/18 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
JS中获取函数调用链所有参数的方法
2015/05/07 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
详解Vuejs2.0之异步跨域请求
2017/04/20 Javascript
ionic2懒加载配置详解
2017/09/01 Javascript
Vue.js 2.5新特性介绍(推荐)
2017/10/24 Javascript
JS块级作用域和私有变量实例分析
2019/05/11 Javascript
五句话帮你轻松搞定js原型链
2020/12/09 Javascript
[03:21]【TI9纪实】Old Boys
2019/08/23 DOTA
Windows下用py2exe将Python程序打包成exe程序的教程
2015/04/08 Python
Django 忘记管理员或忘记管理员密码 重设登录密码的方法
2018/05/30 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
python如何实现数据的线性拟合
2019/07/19 Python
详解Pycharm安装及Django安装配置指南
2020/09/15 Python
Pycharm中使用git进行合作开发的教程详解
2020/11/17 Python
对CSS3选择器的研究(详解)
2016/09/16 HTML / CSS
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
实习老师离校感言
2014/02/03 职场文书
电大会计学自我鉴定
2014/02/06 职场文书
听课评语大全
2014/04/30 职场文书
文明城市标语
2014/06/16 职场文书
法学专业大学生实习自我鉴定
2014/10/05 职场文书
学校政风行风评议心得体会
2014/10/21 职场文书
材料员岗位职责
2015/02/10 职场文书
期末个人总结范文
2015/02/13 职场文书
2016年端午节寄语
2015/12/04 职场文书
Python实现简单的俄罗斯方块游戏
2021/09/25 Python