熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

解析php中的escape函數

2013-11-15 12:31:21  來源: PHP編程 

  采用js對URL中的漢字進行escape編碼
<a href="" onclick="windowopen(product_listphp?p_sort=+escape(腳本之家));">這樣點擊鏈接後的效時
引用%uF%uD%uD%uE%uF
生成了這樣的效果 很明顯用PHP的urldecode()或者base_decode()是無法反解的
解決方法 用PHP寫一個反解函數

復制代碼 代碼如下:
function js_unescape($str){
$ret = ;
$len = strlen($str);
for ($i = ; $i < $len; $i++)
{
if ($str[$i] == % && $str[$i+] == u)
{
$val = hexdec(substr($str $i+ ));
if ($val < xf) $ret = chr($val);
else if($val < x) $ret = chr(xc|($val>>))chr(x|($val&xf)); else $ret = chr(xe|($val>>))chr(x|(($val>>)&xf))chr(x|($val&xf));
$i += ;
}
else if ($str[$i] == %)
{
$ret = urldecode(substr($str $i ));
$i += ;
}
else $ret = $str[$i];
}
return $ret;}

  
注意JS編碼會自動轉換成為UTF 所以必須進行編碼轉換才能得到正確的結果否則會中文亂碼但如果使用UTF-編碼就不用這一步了
代碼如下print iconv(utf gb js_unescape($_REQUEST[p_sort]));
到此我們就成功地反解了js的escape編碼了
如下
另外我找到個用PHP實現js的escape編碼的函數

復制代碼 代碼如下:
function phpescape($str)
{
$sublen=strlen($str);
$retrunString="";
for ($i=;$i<$sublen;$i++)
{
if(ord($str[$i])>=)
{
$tmpString=binhex(iconv("gb""ucs"substr($str$i)));
//$tmpString=substr($tmpString)substr($tmpString);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("/[xxff]|[xxf]+/"$str$r);
$ar = $r[];
foreach($ar as $k=>$v) {
if(ord($v[]) < )
$ar[$k] = rawurlencode($v);
else
$ar[$k] = "%u"binhex(iconv("GB""UCS"$v));
}
return join(""$ar);
}

  
這個函數可以很好的工作但是也許有新手不理解這個函數的原理(比如我)用起來總是不放心現在我就來解釋一下這個函數的原理而且我認為拿別人的代碼來復用好比站在了巨人的肩膀上但是若不理解別人的代碼遲早要掉到地面上
第一句preg_match_all("/[x xff]|[xxf]+/"$str$r);這個是用正則表達式匹配 字符串中所有的字符[xxff] 匹配的是漢字x表示匹配字符的進制編碼[ ] 是類選擇符” 表示任意一個字符這樣[xxff]匹配的是兩個字符其中第一個就是進制從到ff的字符而這恰好就是漢字編碼的第一個字符這樣 就能完整的匹配一個漢字關於unicode中漢字的編碼大家可以到網上搜索一下同理[xxf]+英文字符串因為最早的英文是 ASCII編碼編碼值小於也就是進制的從f"+"表示一個或者多個字符這樣[xxf]+就能匹配連續多個英文字符 串

復制代碼 代碼如下:
$ar = $r[]; //$r[]裡存放是匹配到的數組
foreach($ar as $k=>$v) {
if(ord($v[]) < ) //假如字符編碼值小於說明是個英文字符
$ar[$k] = rawurlencode($v); //直接用rawurlencode編碼
else
$ar[$k] = "%u"binhex(iconv("GB""UCS"$v)); //否則的話用iconv函數把漢字轉變成ucs編碼也就是unicode編碼
}

  
在javascript中就可以用unescape來解碼了
uuFFE 和ueufa來匹配中文
但好像前者包含漢字下的A¥等 後者可能是純漢字
其中解碼函數為

復制代碼 代碼如下:
function unescape($str) {
$str = rawurldecode($str);
preg_match_all("/%u{}|&#x{};|&#d+;|+/U"$str$r);
$ar = $r[];
foreach($ar as $k=>$v) {
if(substr($v) == "%u")
$ar[$k] = iconv("UCS""GBK"pack("H"substr($v)));
elseif(substr($v) == "&#x")
$ar[$k] = iconv("UCS""GBK"pack("H"substr($v)));
elseif(substr($v) == "&#") {
$ar[$k] = iconv("UCS""GBK"pack("n"substr($v)));
}
}
return join(""$ar);
}

  
編碼范圍
GBK (GB/GB)
xxff GBK雙字節編碼范圍
xxf ASCII
xaxff 中文
xxff 中文
UTF (Unicode)
ueufa (中文)
xxF (韓文
xACxDA (韓文)
uue (日文)
ps: 韓文是大於[ufa]的字符
正則例子:
preg_replace("/([xxff])/"""$str);
preg_replace("/([ueufa])/"""$str);


From:http://tw.wingwit.com/Article/program/PHP/201311/21103.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.