urldecode

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

urldecode解码 URL 编码的字符串

描述

urldecode(string $string): string

解码给定字符串中的任何 %## 编码。加号 ('+') 被解码为空格字符。

参数

string

要解码的字符串。

返回值

返回解码后的字符串。

示例

示例 #1 urldecode() 示例

<?php
$query
= "my=apples&are=green+and+red";

foreach (
explode('&', $query) as $chunk) {
$param = explode("=", $chunk);

if (
$param) {
printf("Value for parameter \"%s\" is \"%s\"<br/>\n", urldecode($param[0]), urldecode($param[1]));
}
}
?>

注释

警告

超全局变量 $_GET$_REQUEST 已经被解码。在 $_GET$_REQUEST 中的元素上使用 urldecode() 可能会导致意想不到的危险结果。

参见

添加注释

用户贡献的注释 20 个注释

39
alejandro at devenet dot net
13 年前
当客户端发送 Get 数据时,utf-8 字符编码在 urlencode 方面存在一个小问题。
考虑 "º" 字符。
一些客户端可以发送(例如)
foo.php?myvar=%BA
而其他客户端发送
foo.php?myvar=%C2%BA (正确的 url 编码)

在这种情况下,您将值分配给变量 $x

<?php
$x
= $_GET['myvar'];
?>

$x 存储:在第一种情况下是 "�"(错误),在第二种情况下是 "º"(正确)

要解决这个问题,您可以使用以下函数

<?php
function to_utf8( $string ) {
// 来自 http://w3.org/International/questions/qa-forms-utf-8.html
if ( preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # 非超长 2 字节
| \xE0[\xA0-\xBF][\x80-\xBF] # 不包括超长字节
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # 直接 3 字节
| \xED[\x80-\x9F][\x80-\xBF] # 不包括代理项
| \xF0[\x90-\xBF][\x80-\xBF]{2} # 平面 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # 平面 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # 平面 16
)*$%xs'
, $string) ) {
return
$string;
} else {
return
iconv( 'CP1252', 'UTF-8', $string);
}
}
?>

并以这种方式分配

<?php
$x
= to_utf8( $_GET['myvar'] );
?>

$x 存储:在第一种情况下是 "º"(正确),在第二种情况下是 "º"(正确)

解决了许多 i18n 问题。

请在下一个 PHP 版本中修复 $_GET 变量的自动 urldecode。

再见。

Alejandro Salamanca
13
Visual
18 年前
如果您在 javascript 中转义字符串,并希望使用 urldecode 在 PHP 中对其进行解码(或者希望 PHP 在将它们放入查询字符串或 POST 请求时自动解码它们),您应该使用 javascript 函数 encodeURIComponent() 而不是 escape()。然后您就不需要上一个评论中提到的任何自定义 utf_urldecode 函数。
4
tomas at penajaca dot com dot br
21 年前
urldecode 不解码 "%0",而是将其绕过。当您使用固定长度字符串时,这会导致问题。

您可以使用以下函数。

function my_urldecode($string){

$array = split ("%",$string);

if (is_array($array)){
while (list ($k,$v) = each ($array)){
$ascii = base_convert ($v,16,10);
$ret .= chr ($ascii);
}
}
return ("$ret");
}
4
rosty dot kerei at gmail dot com
18 年前
此函数不解码 unicode 字符。我写了一个可以解码 unicode 字符的函数。

function unicode_urldecode($url)
{
preg_match_all('/%u([[:alnum:]]{4})/', $url, $a);

foreach ($a[1] as $uniord)
{
$dec = hexdec($uniord);
$utf = '';

if ($dec < 128)
{
$utf = chr($dec);
}
else if ($dec < 2048)
{
$utf = chr(192 + (($dec - ($dec % 64)) / 64));
$utf .= chr(128 + ($dec % 64));
}
else
{
$utf = chr(224 + (($dec - ($dec % 4096)) / 4096));
$utf .= chr(128 + ((($dec % 4096) - ($dec % 64)) / 64));
$utf .= chr(128 + ($dec % 64));
}

$url = str_replace('%u'.$uniord, $utf, $url);
}

return urldecode($url);
}
4
Jan Vratny
16 年前
mkaganer at gmail dot com

尝试在 javascript 中使用 encodeURI() 而不是 encode()。这对我有效,而您的解决方案在某些国家字符(至少在 IE6 中)不起作用。
1
bloodjazman at gmail dot com
4 年前
"+" 被空格替换,符合 HTML x-www-form-url-encoded 媒体类型
参见 http://www.faqs.org/rfcs/rfc1866.html
3
Joe
16 年前
值得指出的是,如果您正在使用 AJAX 并需要编码发送到 PHP 应用程序的字符串,您可能不需要在 PHP 中对其进行解码。

<?php
echo stripslashes(nl2br($_POST['message']));
?>

如果消息使用 javascript 代码进行编码,则将正确输出发送的消息

message = encodeURIComponent(message)

并使用 AJAX POST 请求以以下标题发送
ajaxVar.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
1
Soaku
6 年前
即使 $_GET 和 $_REQUEST 自动解码,但某些其他变量不会。例如 $_SERVER["REQUEST_URI"]。使用时请记住对其进行解码。
1
OZLperez11 at gmail dot com
8 年前
当通过 AJAX POST 数据发送包含与号 (&) 的字符串时,请确保在 JavaScript 端使用 encodeURIComponent(),并在 PHP 端对该变量使用 urldecode()。我发现传递原始与号很棘手,因此这是对我有用的方法。
<?php

$_POST
["data"] = "one%20%26%20two";
$a = urldecode($_POST["data"); // -> "one & two"

?>
出于某种原因,包含与号的变量会保持编码状态,而其他 POST 变量则会自动解码。我在提交之前将来自 HTML 表单的数据连接在一起,如果你想知道浏览器端发生了什么,可以参考这个信息。
1
aravind dot a dot padmanabhan at gmail dot com
10 年前
似乎 $_REQUEST 全局参数仅在内容类型为 application/x-www-form-urlencoded 时才会自动解码。

如果内容类型为 multipart/form-data,数据将保持未解码状态。我们必须在我们的端手动处理解码。
2
Matt Johnson
19 年前
提醒一下:如果你考虑对 $_GET 变量使用 urldecode(),请不要这样做!

错误的 PHP

<?php
# 错误代码!请勿使用!
$term = urldecode($_GET['sterm']);
?>

正确的 PHP

<?php
$term
= $_GET['sterm'];
?>

Web 服务器会在 $_GET 到达你之前对其进行 urldecode!

对 $_GET 使用 urldecode() 会导致极度糟糕的结果,尤其是在你假设 GET 上的“魔法引号”可以保护你免受引号攻击时。

提示:script.php?sterm=%2527 [...]

PHP 会将此“接收”为 %27,而你的 urldecode() 会将其转换为 “'”(单引号)。当注入到 SQL 或依赖于转义引号的某些 PHP 函数中时,这可能会造成灾难性的后果——魔法引号无法正确检测到这一点,也无法保护你!

这种“常见错误”是影响 phpBB < 2.0.11 的 Santy.A 蠕虫的根本原因之一。
-1
smolniy at mtu dot ru
21 年前
为了兼容新旧浏览器

%xx -> char
%u0xxxx -> char

function unicode_decode($txt) {
$txt = ereg_replace('%u0([[:alnum:]]{3})', '&#x\1;',$txt);
$txt = ereg_replace('%([[:alnum:]]{2})', '&#x\1;',$txt);
return ($txt);
}
-2
mkaganer at gmail dot com
16 年前
B.H.

我在将 $_GET 中的 Unicode 编码数据(如:%u05D8%u05D1%u05E2)转换为 UTF8 以进行服务器端处理时遇到了麻烦。这些数据是由 JavaScript 的 escape() 函数生成的。

最后,我找到了一个简单的解决方案(只有 3 行代码)来实现它(至少在我的配置中是有效的)。

<?php
function utf8_urldecode($str) {
$str = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($str));
return
html_entity_decode($str,null,'UTF-8');;
}
?>

请注意,html_entity_decode() 的文档说明“对多字节字符集的支持是在 PHP 5.0.0 中添加的”,因此这可能不适用于 PHP 4。
-5
spam at soiland dot no
19 年前
关于 reg_var 和“HTML 保留字”

不要添加空格,就像用户建议的那样。

相反,请按照所有 HTML 标准的要求,在你的 HTML 中将 URL 中的 & 编码为 &amp;。

& 在“大多数情况下”有效的原因是浏览器很宽容,它们只是将 & 解码为 & 符号。只要你有一个与 HTML 实体匹配的变量,例如“gt”或“copy”等,就会出现问题。URL 中的 &copy 会被解释为 &copy;(; 在 SGML 中不是必需的,因为它“隐含”在内。在 XML 中,它是必需的)。结果与你将实际字符插入源代码中相同,例如,通过按 alt-0169 并在 HTML 中实际插入 ?。

也就是说,请使用

<a href="?name=stain&amp;fish=knott">mylink</a>

请注意,&amp; 的解码为 & 是在浏览器中完成的,它是在将 HTML 拆分为标签、属性和内容后立即完成的,但它适用于属性和内容。

这意味着你应该将任何其他 HTML 属性中的所有 & 实体化,例如,在具有以下内容的表单中:
<input name="fish" value="fish &amp; fries" />.
-5
regindk at hotmail dot com
21 年前
关于:bellani at upgrade4 dot it
$str = "pippo.php?param1=&reg_var";
echo rawurldecode($str);
得到
pippo.php?param1=?_var
你应该用正确的 W3C &amp; 替换 &,而不是使用空格。
像这样
$str = "pippo.php?param1=&amp;reg_var";
echo rawurldecode($str);
-6
mail dot roliveira at gmail dot com
15 年前
通过 AJAX (POST) 将 JSON 发送到 PHP

如果你通过 AJAX 发送 JSON 数据,并在 JavaScript 中使用 encodeURIComponent 对其进行编码,那么在 PHP 端,你需要对你的 $_POST['myVar'] 使用 stripslashes。

完成此操作后,你就可以对你的字符串使用 json_decode。

例如。

<?php
// 首先在 JavaScript 中使用 encodeURIComponent 对字符串进行编码
// 接收 JSON 字符串并将其准备为 json_decode
$jsonStr = stripslashes ($_POST['action']);
// 解码为 PHP 对象
$json = json_decode ($jsonStr);

// $json 现在是一个 PHP 对象
?>
-6
bellani at upgrade4 dot it
21 年前
如果你有一个“HTML 保留字”作为变量名(例如“reg_var”),并且你将其作为参数传递,那么你将得到一个错误的 URL。例如

<a href="pippo.php?param1=&reg_var=">go</a>

你将得到一个错误的 URL,如下所示

"pippo.php?param1=?_var"

只需在 "&" 和 "reg_var" 之间添加一个空格,它就可以正常工作!

<a href="pippo.php?param1=& reg_var=">go</a>

"pippo.php?param1=&%20reg_var"

有效!!
-13
caribe at flash-brasil dot com dot br
20 年前
为了使 urldecode 能够处理巴西字符,如 ? ? ? 和其他字符,请放置以下标头命令:

header('Content-type: text/html; charset=UTF-8');
-11
igjav at cesga dot es
22 年前
这似乎可以在大多数浏览器和字符编码配置之间正确解码。特别适合直接解析 URL,因为它会在环境变量中出现。

function crossUrlDecode($source) {
$decodedStr = '';
$pos = 0;
$len = strlen($source);

while ($pos < $len) {
$charAt = substr ($source, $pos, 1);
if ($charAt == '?') {
$char2 = substr($source, $pos, 2);
$decodedStr .= htmlentities(utf8_decode($char2),ENT_QUOTES,'ISO-8859-1');
$pos += 2;
}
elseif(ord($charAt) > 127) {
$decodedStr .= "&#".ord($charAt).";";
$pos++;
}
elseif($charAt == '%') {
$pos++;
$hex2 = substr($source, $pos, 2);
$dechex = chr(hexdec($hex2));
if($dechex == '?') {
$pos += 2;
if(substr($source, $pos, 1) == '%') {
$pos++;
$char2a = chr(hexdec(substr($source, $pos, 2)));
$decodedStr .= htmlentities(utf8_decode($dechex . $char2a),ENT_QUOTES,'ISO-8859-1');
}
else {
$decodedStr .= htmlentities(utf8_decode($dechex));
}
}
else {
$decodedStr .= $dechex;
}
$pos += 2;
}
else {
$decodedStr .= $charAt;
$pos++;
}
}

return $decodedStr;
}
-14
Anonymous
20 年前
nataniel,你的函数需要如下修正:

------------------------------------------------------------
function unicode_decode($txt) {
return ereg_replace('%u([[:alnum:]]{4})', '&#x\1;',$txt);
}
------------------------------------------------------------

因为一些代码不是以 %u0 开头的。
To Top