略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: urldecode

2024-12-22

urldecode

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

urldecode解码已编码的 URL 字符串

说明

urldecode(string $str): string

解码给出的已编码字符串中的任何 %##。 加号('+')被解码成一个空格字符。

参数

str

要解码的字符串。

返回值

返回解码后的字符串。

范例

示例 #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() 将会导致不可预计和危险的结果。

参见

add a noteadd a note

User Contributed Notes 22 notes

up
40
alejandro at devenet dot net
11 years ago
When the client send Get data, utf-8 character encoding have a tiny problem with the urlencode.
Consider the "º" character.
Some clients can send (as example)
foo.php?myvar=%BA
and another clients send
foo.php?myvar=%C2%BA (The "right" url encoding)

in this scenary, you assign the value into variable $x

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

$x store: in the first case "�" (bad) and in the second case "º" (good)

To fix that, you can use this function:

<?php
function to_utf8( $string ) {
// From http://w3.org/International/questions/qa-forms-utf-8.html
   
if ( preg_match('%^(?:
      [\x09\x0A\x0D\x20-\x7E]            # ASCII
    | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
    | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
    | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
    | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
    | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
    | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
)*$%xs'
, $string) ) {
        return
$string;
    } else {
        return
iconv( 'CP1252', 'UTF-8', $string);
    }
}
?>

and assign in this way:

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

$x store: in the first case "º" (good) and in the second case "º" (good)

Solve a lot of i18n problems.

Please fix the auto-urldecode of $_GET var in the next PHP version.

Bye.

Alejandro Salamanca
up
19
Visual
16 years ago
If you are escaping strings in javascript and want to decode them in PHP with urldecode (or want PHP to decode them automatically when you're putting them in the query string or post request), you should use the javascript function encodeURIComponent() instead of escape(). Then you won't need any of the fancy custom utf_urldecode functions from the previous comments.
up
6
tomas at penajaca dot com dot br
18 years ago
urldecode does not decode "%0"  bypassing it. I can cause troble when you are working with fixed lenght strings.

You can you the function below.

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");
}
up
8
Jan Vratny
14 years ago
mkaganer at gmail dot com:

try using encodeURI() instead of encode() in javascript. That worked for me, while your solution did not on __some__ national characters (at least in IE6).
up
8
Matt Johnson
17 years ago
A reminder: if you are considering using urldecode() on a $_GET variable, DON'T!

Evil PHP:

<?php
# BAD CODE! DO NOT USE!
$term = urldecode($_GET['sterm']);
?>

Good PHP:

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

The webserver will arrange for $_GET to have been urldecoded once already by the time it reaches you!

Using urldecode() on $_GET can lead to extreme badness, PARTICULARLY when you are assuming "magic quotes" on GET is protecting you against quoting.

Hint: script.php?sterm=%2527 [...]

PHP "receives" this as %27, which your urldecode() will convert to "'" (the singlequote). This may be CATASTROPHIC when injecting into SQL or some PHP functions relying on escaped quotes -- magic quotes rightly cannot detect this and will not protect you!

This "common error" is one of the underlying causes of the Santy.A worm which affects phpBB < 2.0.11.
up
5
rosty dot kerei at gmail dot com
16 years ago
This function doesn't decode unicode characters. I wrote a function that does.

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);
}
up
4
OZLperez11 at gmail dot com
6 years ago
When sending a string via AJAX POST data which contains an ampersand (&), be sure to use encodeURIComponent() on the javascript side and use urldecode() on the php side for whatever variable that was. I've found it tricky to transfer raw ampersands and so this is what worked for me:
<?php

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

?>
For some reason, a variable with an ampersand would stay encoded while other POST variables were automatically decoded. I concatenated data from an html form before submitting, in case you wish to know what happened on the browser end.
up
2
Joe
14 years ago
It's worth pointing out that if you are using AJAX and need to encode strings that are being sent to a PHP application, you may not need to decode them in PHP.

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

Will properly output a message sent with the javascript code if the message is encoded:

message = encodeURIComponent(message)

And is sent with an AJAX POST request with the header:
ajaxVar.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
up
2
smolniy at mtu dot ru
19 years ago
For compatibility of new and old brousers:

%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);
}
up
1
aravind dot a dot padmanabhan at gmail dot com
8 years ago
It seems that the $_REQUEST global parameter is automatically decoded only if the content type is application/x-www-form-urlencoded.

if the content type is multipart/form-data. the data remains un-decoded. and we have to manually handle the decoding at our end
up
0
spiritclimbing
29 days ago
<a href=https://rockclimbing-en.site>Spirit Climbing</a>

Экспромтом три спортсмена бунтовали сверху высочайшую ступень пьедестала чемпионатов мира.
<a href=https://rockclimbing-en.site>Spirit Climbing</a>
up
0
bloodjazman at gmail dot com
2 years ago
"+" replaced by space according to HTML x-www-form-url-encoded media type
see http://www.faqs.org/rfcs/rfc1866.html
up
0
Soaku
4 years ago
Even if $_GET and $_REQUEST are decoded automatically, some other variables aren't. For example $_SERVER["REQUEST_URI"]. Remember to decode it when using.
up
0
mkaganer at gmail dot com
14 years ago
B.H.

I had troubles converting Unicode-encoded data in $_GET (like this: %u05D8%u05D1%u05E2) which is generated by JavaScript's escape() function to UTF8 for server-side processing.

Finally, i've found a simple solution (only 3 lines of code) that does it (at least in my configuration):

<?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');;
  }
?>

note that documentation for html_entity_decode() states that "Support for multi-byte character sets was added at PHP 5.0.0" so this might not work for PHP 4
up
-3
spam at soiland dot no
17 years ago
About reg_var and "html reserved words"

Do not add spaces as the user suggests.

Instead, do what all HTML standards says and encode & in URLs as &amp; in your HTML.

The reason why & works "most of the time" is that browsers are forgiving and just decode the & as the &-sign. This breaks whenever you have a variable that matches an HTML entity, like "gt" or "copy" or whatever. &copy in your URL will be interpreted as &copy;  (the ; is not mandatory in SGML as it is "implied". In XML it is mandatory.).   The result will be the same as if you had inserted the actual character into your source code, for instance by pressing alt-0169 and actually inserted ? in your HTML.

Ie, use:

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

Note that the decoding of &amp; to & is done in the browser, and it's done right after splitting the HTML into tags, attributes and content, but it works both for attributes and content.

This mean you should &entitify all &-s in any other HTML attributes as well, such as in a form with
<input name="fish" value="fish &amp; fries" />.
up
-5
mail dot roliveira at gmail dot com
13 years ago
Send json to PHP via AJAX (POST)

If you send json data via ajax, and encode it with encodeURIComponent in javascript, then on PHP side, you will have to do stripslashes on your $_POST['myVar'].

After this, you can do json_decode on your string.

Ex.:

<?php
// first use encodeURIComponent on javascript to encode the string
// receive json string and prepare it to json_decode
$jsonStr = stripslashes ($_POST['action']);
// decode to php object
$json = json_decode ($jsonStr);

// $json is now a php object
?>
up
-5
regindk at hotmail dot com
19 years ago
About: bellani at upgrade4 dot it
$str = "pippo.php?param1=&reg_var";
echo rawurldecode($str);
Gives:
pippo.php?param1=?_var
Instead of using a space you should exchange & with the correct W3C &amp;
Like this:
$str = "pippo.php?param1=&amp;reg_var";
echo rawurldecode($str);
up
-6
igjav at cesga dot es
20 years ago
This seems to decode correctly between most browsers and charater coding configurations. Specially indicated for direct parsing of URL as it comes on environment variables:

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;
}
up
-7
bellani at upgrade4 dot it
19 years ago
If you have a "html reserved word" as variable name (i.e. "reg_var") and you pass it as an argument you will get  a wrong url. i.e.

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

you will get a wrong url like this

"pippo.php?param1=?_var"

Simply add a space between "&" and "reg_var" and it will work!

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

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

Works!!
up
-13
caribe at flash-brasil dot com dot br
18 years ago
To allow urldecode to work with Brazilian characters as ? ? ? and other just place this header command :

header('Content-type: text/html; charset=UTF-8');
up
-11
Anonymous
18 years ago
nataniel, your function needs to be corrected as follows:

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

since some codes does not begin with %u0.
up
-6
navalnybaplemo
9 months ago
По сути своей "Умног голосование" сегодня это политическая стратегия, изобретена российским внесистемным политическим деятелем Алексеем Навальным как средство борьбы с "Единой Россией" умного голосования, проголосовать за главного оппонента кандидата "Единой России" во многих одномандатных округах везде по стране, вне зависимости от общественно-политической принадлежности и взглядов этого соперника.
Сегодня Алексей Навальный пребывает в тюрьме, и его собственное политическое движение заявлено "противозаконна", потому оно не имеет права действовать в России.
Значение представленной стратегии подрезать крылья власти Единой России, а не гарантировать успех любого другого общественно-политического движения.
Как к примеру, в случае, если у либералов намного больше вероятности выиграть избирательный район, нужно проголосовать за него, когда даже вы ненавидите их.
Скажем, когда у коммуниста намного больше шансов победить избирательный округ, следует отдать голос за него, если вы лично этого не жаждете.


<a href=https://navalny-team.com/>полиция ходит по квартирам умное голосование</a>

官方地址:https://www.php.net/manual/en/function.urldecode.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3