解析php中的escape函數(shù)
更新時間:2013年06月29日 09:42:36 作者:
本篇文章是對php中的escape函數(shù)進行了詳細的分析介紹,需要的朋友參考下
采用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寫一個反解函數(shù):
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編碼會自動轉(zhuǎn)換成為UTF-8, 所以必須進行編碼轉(zhuǎn)換才能得到正確的結(jié)果,否則會中文亂碼。但如果使用UTF-8編碼就不用這一步了。
代碼如下:print iconv('utf-8', 'gb2312', js_unescape($_REQUEST['p_sort']));
到此我們就成功地反解了js的escape編碼了。
如下:
另外我找到個用PHP實現(xiàn)js的escape編碼的函數(shù):
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中不支持中文,用它傳送中文數(shù)據(jù)就會出現(xiàn)數(shù)據(jù)丟失或者亂碼,必須在傳 送前對要發(fā)送的字符串進行編碼,由于傳送過去需要用js進行數(shù)據(jù)解析,考慮到js中有unescape函數(shù),故若在php中有個escape函數(shù),對數(shù)據(jù) 進行編碼,在客戶端用unescape進行 解碼,這樣就會方便很多。
先在網(wǎng)上搜索一把,很多用php實現(xiàn)的escape函數(shù),大同小異,比如下面一個:
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);
}
這個函數(shù)可以很好的工作,但是,也許有新手不理解這個函數(shù)的原理(比如我),用起來總是不放心,現(xiàn)在我就來解釋一下這個函數(shù)的原理。而且我認為,拿別人的代碼來復用,好比站在了巨人的肩膀上,但是若不理解別人的代碼,遲早要掉到地面上。
第一句:preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);這個是用正則表達式匹配 字符串中所有的字符,[\x80-\xff]. 匹配的是漢字,\x表示匹配字符的16進制編碼,[ ] 是類選擇符,“.” 表示任意一個字符,這樣[\x80-\xff].匹配的是兩個字符,其中第一個就是16進制從80到ff的字符,而這恰好就是漢字編碼的第一個字符。這樣 就能完整的匹配一個漢字。關(guān)于unicode中漢字的編碼,大家可以到網(wǎng)上搜索一下。同理,[\x01-\x7f]+英文字符串,因為最早的英文是 ASCII編碼,編碼值小于128,也就是16進制的從01到7f,"+"表示一個或者多個字符,這樣[\x01-\x7f]+就能匹配連續(xù)多個英文字符 串。
$ar = $r[0]; //$r[0]里存放是匹配到的數(shù)組
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函數(shù)把漢字轉(zhuǎn)變成ucs-2編碼,也就是unicode編碼
}
在javascript中就可以用unescape來解碼了
\u0391-\uFFE5 和\u4e00-\u9fa5來匹配中文
但好像前者包含漢字下的A-¥等 后者可能是純漢字。
其中解碼函數(shù)為:
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雙字節(jié)編碼范圍
\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);
<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寫一個反解函數(shù):
復制代碼 代碼如下:
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編碼會自動轉(zhuǎn)換成為UTF-8, 所以必須進行編碼轉(zhuǎn)換才能得到正確的結(jié)果,否則會中文亂碼。但如果使用UTF-8編碼就不用這一步了。
代碼如下:print iconv('utf-8', 'gb2312', js_unescape($_REQUEST['p_sort']));
到此我們就成功地反解了js的escape編碼了。
如下:
另外我找到個用PHP實現(xiàn)js的escape編碼的函數(shù):
復制代碼 代碼如下:
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中不支持中文,用它傳送中文數(shù)據(jù)就會出現(xiàn)數(shù)據(jù)丟失或者亂碼,必須在傳 送前對要發(fā)送的字符串進行編碼,由于傳送過去需要用js進行數(shù)據(jù)解析,考慮到js中有unescape函數(shù),故若在php中有個escape函數(shù),對數(shù)據(jù) 進行編碼,在客戶端用unescape進行 解碼,這樣就會方便很多。
先在網(wǎng)上搜索一把,很多用php實現(xiàn)的escape函數(shù),大同小異,比如下面一個:
復制代碼 代碼如下:
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);
}
這個函數(shù)可以很好的工作,但是,也許有新手不理解這個函數(shù)的原理(比如我),用起來總是不放心,現(xiàn)在我就來解釋一下這個函數(shù)的原理。而且我認為,拿別人的代碼來復用,好比站在了巨人的肩膀上,但是若不理解別人的代碼,遲早要掉到地面上。
第一句:preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);這個是用正則表達式匹配 字符串中所有的字符,[\x80-\xff]. 匹配的是漢字,\x表示匹配字符的16進制編碼,[ ] 是類選擇符,“.” 表示任意一個字符,這樣[\x80-\xff].匹配的是兩個字符,其中第一個就是16進制從80到ff的字符,而這恰好就是漢字編碼的第一個字符。這樣 就能完整的匹配一個漢字。關(guān)于unicode中漢字的編碼,大家可以到網(wǎng)上搜索一下。同理,[\x01-\x7f]+英文字符串,因為最早的英文是 ASCII編碼,編碼值小于128,也就是16進制的從01到7f,"+"表示一個或者多個字符,這樣[\x01-\x7f]+就能匹配連續(xù)多個英文字符 串。
復制代碼 代碼如下:
$ar = $r[0]; //$r[0]里存放是匹配到的數(shù)組
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函數(shù)把漢字轉(zhuǎn)變成ucs-2編碼,也就是unicode編碼
}
在javascript中就可以用unescape來解碼了
\u0391-\uFFE5 和\u4e00-\u9fa5來匹配中文
但好像前者包含漢字下的A-¥等 后者可能是純漢字。
其中解碼函數(shù)為:
復制代碼 代碼如下:
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雙字節(jié)編碼范圍
\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);
您可能感興趣的文章:
- escape unescape的php下的實現(xiàn)方法
- php utf-8轉(zhuǎn)unicode的函數(shù)
- php escape URL編碼
- php 正確解碼javascript中通過escape編碼后的字符
- php UTF-8、Unicode和BOM問題
- PHP下escape解碼函數(shù)的實現(xiàn)方法
- 在PHP中實現(xiàn)Javascript的escape()函數(shù)代碼
- PHP中正則表達式對UNICODE字符碼的匹配方法
- 如何使用PHP實現(xiàn)javascript的escape和unescape函數(shù)
- 淺析PHP中的UNICODE 編碼與解碼
- PHP函數(shù)addslashes和mysql_real_escape_string的區(qū)別
- PHP解碼unicode編碼的中文字符代碼分享
- PHP解密Unicode及Escape加密字符串
相關(guān)文章
php靜態(tài)編譯swoole-cli并調(diào)用rust的動態(tài)鏈接庫
這篇文章主要為大家介紹了靜態(tài)編譯swoole-cli并調(diào)用rust的動態(tài)鏈接庫實現(xiàn)步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07判斷php數(shù)組是否為索引數(shù)組的實現(xiàn)方法
本篇文章是對判斷php數(shù)組是否為索引數(shù)組的方法進行了詳細的分析介紹,需要的朋友參考下2013-06-06php實現(xiàn)的返回數(shù)據(jù)格式化類實例
這篇文章主要介紹了php實現(xiàn)的返回數(shù)據(jù)格式化類及其應用實例,包括針對XML、JSON等的格式化,非常具有實用價值,需要的朋友可以參考下2014-09-09