總結:此函式與 urldecode 函式的唯一區別在於「+」字元不會被轉換。
(PHP 4、PHP 5、PHP 7、PHP 8)
rawurldecode — 解碼 URL 編碼字串
string
要解碼的 URL。
傳回已解碼的 URL,作為字串。
範例 1 rawurldecode() 範例
<?php
echo rawurldecode('foo%20bar%40baz'); // foo bar@baz
?>
註解:
rawurldecode() 不會將加號符號 ('+') 解碼為空格。urldecode() 會。
大家好 =) 我叫 Javier,來自阿根廷。
我遇到一個小問題,像是 ñ、"Ñ"、"á"、"é"、"í" 等拉丁字元。
它們無法使用 rawurlencode() 解碼,所以我製作了這個
<?php
function urlRawDecode($raw_url_encoded)
{
# 十六進位轉換表
$hex_table = array(
0 => 0x00,
1 => 0x01,
2 => 0x02,
3 => 0x03,
4 => 0x04,
5 => 0x05,
6 => 0x06,
7 => 0x07,
8 => 0x08,
9 => 0x09,
"A"=> 0x0a,
"B"=> 0x0b,
"C"=> 0x0c,
"D"=> 0x0d,
"E"=> 0x0e,
"F"=> 0x0f
);
# 修正拉丁字元問題
if(preg_match_all("/\%C3\%([A-Z0-9]{2})/i", $raw_url_encoded,$res))
{
$res = array_unique($res = $res[1]);
$arr_unicoded = array();
foreach($res as $key => $value){
$arr_unicoded[] = chr(
(0xc0 | ($hex_table[substr($value,0,1)]<<4))
| (0x03 & $hex_table[substr($value,1,1)])
);
$res[$key] = "%C3%" . $value;
}
$raw_url_encoded = str_replace(
$res,
$arr_unicoded,
$raw_url_encoded
);
}
# 返回解碼後的原始 URL 編碼資料
return rawurldecode($raw_url_encoded);
}
print urlRawDecode("%C3%A1%C3%B1");
// 輸出:
// áñ
?>
例如,您有像 "%C3%B1" 這樣編碼的字元 "ñ"。
這不過是 0xc3 和 0xb1,
它們是二進位數字,(HHHH LLLL,其中 HHHH=高位,LLLL=低位)。
0xc3 = 1100 0011(二進位 8 位元字組),0xb1 = 1011 0001(二進位 8 位元字組),
為了將原始編碼字元轉換為 ASCII,我們必須在
這兩個運算元(0xc3 和 0xb1)之間進行布林運算,布林代數由喬治
布爾定義,我們在這裡需要使用它們。我們要使用的第一個是
邏輯 OR(「|」或「管線」)和邏輯 AND(「&」或「與符號」)。
邏輯 OR 意味著以下真值表
a b (a OR b)
0 0 0
0 1 1 (a OR b 或兩者,a 和 b 必須都為真才能獲得真結果)
1 0 1
1 1 1
邏輯 AND 意味著以下真值表
a b (a AND b)
0 0 0
0 1 0
1 0 0
1 1 1(a 和 b 都必須為真才能獲得真結果)
因此,在這裡我們必須對 0xc3 和 0xb1 的高位 nibble 進行邏輯 OR 運算,
一個 nibble 是一個半位元組(4 位元),因此我們必須在
1100 (0xc) 和 1011 (0xb) 之間進行邏輯 OR 運算,我們將得到:1111 (0xf),然後我們必須在
兩個低位 nibble、0011 (0x3) 和 0001 (0x1) 之間進行邏輯 AND 運算,我們將得到
這個:0001,所以,如果我們想看到最終結果,我們必須將高位和低位
nibble 放在它的位元組位置,像這樣:1111 0001 (0xf1),這不過是
「ñ」(要檢查這個,請嘗試以下操作:print(chr(0xf1));)。
這個「<<」是邏輯左移,如果我們有這個二進位數字 0001 (1),然後我們進行
0001 << 2,我們將得到 0100 (4),右邊的位元會用 0 填充。
<?php
# 轉換範例 %C3%B1 為 ASCII (0x71)
print(
chr(
(0xc0|0x0b<<4) | (0x03&0x01)
)
);
// 輸出結果為:
// ñ
// 1100 0000 OR 1011 0000 = 1111 0000 (0xf0)
// 0000 0011 AND 0000 0001 = 0000 0001 (0x01)
// 1111 0000 OR 0000 0001 = 1111 0001 (0xf1)
?>
PS: 非常抱歉我的英文不好,我知道很糟糕 :P
請注意,如果輸出不是有效的 UTF-8,`rawurldecode` 不會以任何方式警告您。
例如,如果傳遞給函式的輸入只是 "%C5",由於 C 的二進制表示為 1100,而以 110 開頭的 UTF-8 字元後面應接著另一個字元,則 `rawurldecode` 的結果只會是一個位元組 (值為 \xC5),這不是正確的 UTF-8。
對比一下,例如 Javascript 會警告您這一點
JAVASCRIPT
decodeURI("%C5")
URIError: URI 格式不正確
decodeURIComponent("%C5")
URIError: URI 格式不正確
unescape("%C5")
"Å"
PHP
var_dump(rawurldecode("%C5"))
string(1) "▒"
php -v
PHP 5.3.6 (cli) (建置於:2012 年 10 月 4 日 10:19:07)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH
假設您在客戶端和伺服器之間傳遞一些資料,其結構或多或少類似陣列。
如果欄位名稱中使用 [] 括號不夠 (或者由於某些原因不符合專案的其餘部分),您可能必須使用具有多個不同分隔符號的字串 (列、欄位、欄位內的列等)。
為了確保資料不會被誤認為是分隔符號,您可以使用 JavaScript 的 `encodeURIComponent()` 函式。它可以與 `rawurldecode()` 很好地搭配使用。
一旦傳遞到伺服器端的字串最終被拆分成陣列 (或一組陣列),您可以使用以下函式來遞迴地 `rawurldecode` 陣列。
<?php
function rawurldecode_array(&$arr)
{
foreach (array_keys($arr) as $key)
{
if (is_array($arr[$key]))
{
rawurldecode_array($arr[$key]);
}
else
{
$arr[$key] = rawurldecode($arr[$key]);
}
}
}
$a[0] = rawurlencode("2+1:3?9");
$a["k"] = rawurlencode("@:-/");
$a[-3][0] = rawurlencode("+");
$a[-3][2] = rawurlencode("=_~");
$a[-3]["a"] = rawurlencode("this+is a%test");
echo "<pre>"; print_r($a); echo "</pre>";
rawurldecode_array($a);
echo "<pre>"; print_r($a); echo "</pre>";
?>
程式將輸出
陣列
(
[0] => 2%2B1%3A3%3F9
[k] => %40%3A-%2F
[-3] => 陣列
(
[0] => %2B
[2] => %3D_%7E
[a] => this%2Bis%20a%25test
)
)
陣列
(
[0] => 2+1:3?9
[k] => @:-/
[-3] => 陣列
(
[0] => +
[2] => =_~
[a] => this+is a%test
)
)
http://yemennownews.com