PHP Conference Japan 2024

rawurldecode

(PHP 4, PHP 5, PHP 7, PHP 8)

rawurldecode解码URL编码字符串

描述

rawurldecode(字符串 $string): 字符串

返回一个字符串,其中百分号 (%) 后跟两个十六进制数字的序列已被替换为字面字符。

参数

string

要解码的URL。

返回值

返回解码后的URL,作为字符串。

示例

示例 #1 rawurldecode() 示例

<?php

echo rawurldecode('foo%20bar%40baz'); // foo bar@baz

?>

注释

注意:

rawurldecode() 不会将加号 ('+') 解码为空格。urldecode() 会。

参见

添加注释

用户贡献的注释 4条注释

php dot net at hiddemann dot org
19年前
总而言之:此函数与urldecode函数的唯一区别在于“+”字符不会被转换。
Javier A. Segura at gmail dot com
16年前
大家好 =) 我叫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)之间进行布尔运算
这两个操作数(0xc3和0xb1),布尔代数由George
布尔定义,我们这里需要用到它们。我们将使用的第一个是
逻辑或(“|”或“管道”)和逻辑与(“&”或“与人”)。

逻辑或隐含以下真值表
a b (a 或 b)
0 0 0
0 1 1 (a 或 b 或两者,a 和 b 都必须为真才能得到真结果)
1 0 1
1 1 1

逻辑与隐含以下真值表
a b (a 与 b)
0 0 0
0 1 0
1 0 0
1 1 1 (a 与 b 都必须为真才能得到真结果)

所以,这里我们必须对0xc3和0xb1的高位进行逻辑或运算,
一个半字节是半个字节(4位),所以我们必须在
1100(0xc)和1011(0xb)之间进行逻辑或运算,我们将得到:1111(0xf),然后我们必须
将低位字节 0011 (0x3) 和 0001 (0x1) 进行逻辑与运算,结果为:
0001。因此,要查看最终结果,需要将高位字节和低位字节
放在其字节位置上,如下所示: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 或 1011 0000 = 1111 0000 (0xf0)
// 0000 0011 与 0000 0001 = 0000 0001 (0x01)
// 1111 0000 或 0000 0001 = 1111 0001 (0xf1)

?>

附注:很抱歉我的英语不好,我知道,很糟糕 :P
jakub dot lopuszanski at nasza-klasa dot pl
10年前
请注意,rawurldecode 不会以任何方式警告您输出是否为无效的 UTF-8。
例如,如果传递给函数的输入只是 "%C5",由于 C 在二进制中是 1100,而以 110 开头的 UTF-8 字符后面应该跟另一个字符,因此 rawurldecode 的结果只是一个单字节(值为 \xC5),这不是正确的 UTF-8。
例如,与 Javascript 相比,Javascript 会警告您。

JAVASCRIPT

decodeURI("%C5")
URIError: URI malformed

decodeURIComponent("%C5")
URIError: URI malformed

unescape("%C5")
"Å"

PHP
var_dump(rawurldecode("%C5"))
string(1) "▒"

php -v
PHP 5.3.6 (cli) (built: Oct 4 2012 10:19:07)
版权所有 (c) 1997-2011 PHP 组
Zend Engine v2.3.0,版权所有 (c) 1998-2011 Zend Technologies
带有 Suhosin v0.9.32.1,版权所有 (c) 2007-2010,由 SektionEins GmbH
admin at yemennownews dot com
6年前
假设您在客户端和服务器之间以某种类似数组的结构传递一些数据。

如果在字段名称中使用 [] 方括号不够用(或者由于某种原因不符合项目的其余部分),您可能需要使用包含多个不同分隔符(行、字段、字段内的行等)的字符串。

为了确保数据不会被误认为是分隔符,您可以使用 encodeURIComponent() JavaScript 函数。它与 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
To Top