URL 函数
在线手册:中文  英文

urldecode

(PHP 4, PHP 5)

urldecode解码已编码的 URL 字符串

说明

string urldecode ( string $str )

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

参数

str

要解码的字符串。

返回值

返回解码后的字符串。

范例

Example #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]));
    }
}
?>

注释

Warning

超全局变量 $_GET$_REQUEST 已经被解码了。对 $_GET$_REQUEST 里的元素使用 urldecode() 将会导致不可预计和危险的结果。

参见


URL 函数
在线手册:中文  英文

用户评论:

bobbfwed at comcast dot net (2012-08-01 23:30:59)

Here is a function that converts a URL string into an indexed array like what is stored in the $_GET, $_POST, etc. variables. The URL can be in any of these formats:

d_owner=true&d_ptype=%22true%22&ticket=five+44
or
&d_owner=true&d_ptype=%22true%22&ticket=five+44
or
?d_owner=true&d_ptype=%22true%22&ticket=five+44
or
file.php?d_owner=true&d_ptype=%22true%22&ticket=five+44

<?PHP
// decode URL string into array with values (like in $_GET or $_POST)
function urldecode_to_array ($url) {
  
$ret_ar = array();
  
  if ((
$pos strpos($url'?')) !== false)         // parse only what is after the ?
    
$url substr($url$pos 1);
  if (
substr($url01) == '&')                    // if leading with an amp, skip it
    
$url substr($url1);

  
$elems_ar explode('&'$url);                   // get all variables
  
for ($i 0$i count($elems_ar); $i++) {
    list(
$key$val) = explode('='$elems_ar[$i]); // split variable name from value
    
$ret_ar[urldecode($key)] = urldecode($val);     // store to indexed array
  
}

  return 
$ret_ar;
}
?>

I needed this for some AJAX work I was doing, so I thought it may be useful for others.

jodybrabec at gmail dot com (2011-12-21 16:01:19)

Gets rid of 'amp;' in $_GET param names - so $_GET['amp;myVar'] becomes $_GET['myVar']
Made this because sometimes '&amp;' will wind up in the URL, as in:
http://example.com/index.php?aaa=111&amp;myVar=222
Call this function at the top of your php page:
unmake_amps();

<?php
function unmake_amps() {
    foreach (
$_GET as $g_param=>$g_value) {
        if (
preg_match('/^amp\;(.*)$/i'$g_param)) {
            
$g_paramNew preg_replace('/^amp\;(.*)$/i''$1'$g_param);
            unset(
$_GET[$g_param]);
            if (
$g_paramNew != '') {
                
// Only if $g_paramNew has a value, becaues sometimes '&amp;' winds up at the end of a url ($_GET['amp;'])
                
$_GET[$g_paramNew] = $g_value;
            }
        }
    }
}
?>

Geek note: only for one-dimensional $_GET arrays - too lazy to make this a recursive function.

alejandro at devenet dot net (2010-12-14 18:27:03)

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

chrisstocktonaz at gmail dot com (2010-01-29 10:39:38)

I was looking for a fast way to build a string dsn from a key => value pair array. I came up with the following, simple enough for my purposes.

<?php

$dsn 
= Array(
  
'host' => 'localhost',
  
'port' => 80,
  
'user' => 'foo',
  
'pass' => 'R(I%!JAKSJ(asd'
);

$dsn urldecode(http_build_query($dsnNULL';'));

var_dump($dsn); // host=localhost;port=80;user=foo;pass=R(I%!JAKSJ(asd
?>

mail dot roliveira at gmail dot com (2009-05-19 04:50:18)

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
?>

Jan Vratny (2008-06-12 05:09:32)

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).

Joe (2008-04-03 11:11:33)

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')

mkaganer at gmail dot com (2007-12-04 14:58:12)

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

pedantic at hotmail co jp (2006-11-16 08:22:58)

The following function will decode %uXXXX
sequentially, without temporary data.

<?php

function decode_unicode_url($str)
{
  
$res '';

  
$i 0;
  
$max strlen($str) - 6;
  while (
$i <= $max)
  {
    
$character $str[$i];
    if (
$character == '%' && $str[$i 1] == 'u')
    {
      
$value hexdec(substr($str$i 24));
      
$i += 6;

      if (
$value 0x0080// 1 byte: 0xxxxxxx
        
$character chr($value);
      else if (
$value 0x0800// 2 bytes: 110xxxxx 10xxxxxx
        
$character =
            
chr((($value 0x07c0) >> 6) | 0xc0)
          . 
chr(($value 0x3f) | 0x80);
      else 
// 3 bytes: 1110xxxx 10xxxxxx 10xxxxxx
        
$character =
            
chr((($value 0xf000) >> 12) | 0xe0)
          . 
chr((($value 0x0fc0) >> 6) | 0x80)
          . 
chr(($value 0x3f) | 0x80);
    }
    else
      
$i++;

    
$res .= $character;
  }

  return 
$res substr($str$i);
}
?>

Simple test with japanese characters,
combined with urldecode:

<?php

$str 
decode_unicode_url('%u65E5%u672C%u8A9E');
print(
mb_convert_encoding(urldecode($str), "sjis""euc-jp, utf-8, sjis") . '<br/>');
?>

tikitiki at mybboard dot com (2006-10-05 15:56:40)

Here is a rewritten example that does the same thing but runs cleaner.

<?php
$a 
explode('&'$QUERY_STRING);

foreach(
$a as $key => $b)
{
   
$b split('='$b);
   echo 
'Value for parameter '.htmlspecialchars(urldecode($b[0])).' is '.htmlspecialchars(urldecode($b[1]))."<br />\n";
}
?>

jeffreyd at davis at gmail dot com (2006-08-18 13:05:36)

As a useful variation on the function rosty dot kerei at gmail dot com wrote, I made a quick modification to just plain output the html code. That way a javascript encoded url (or say, a get variable) can actually be written back to the user.
function unicode_urldecode($url)
{
preg_match_all('/%u([[:alnum:]]{4})/', $url, $a);

foreach ($a[1] as $uniord)
{
$utf = '&#x' . $uniord . ';';
$url = str_replace('%u'.$uniord, $utf, $url);
}

return urldecode($url);
}

Visual (2006-05-18 12:02:28)

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.

rosty dot kerei at gmail dot com (2006-04-19 09:40:33)

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

Aardvark (2006-03-07 13:20:46)

The function below can be used to convert a query parameter resulting from applying the JavaScript escape function to a Unicode string back to Unicode. The function was modified from a previously published function to handle escaped ASCII values in the range 128-255 which are converted to standard (and not Unicode) escapes by the escape function. The option parameter allows an altenative encoding to UTF-8 to be apploed. (More and related info can be found at http://www.kanolife.com/escape/).
function code2utf($num){
if($num<128)
return chr($num);
if($num<1024)
return chr(($num>>6)+192).chr(($num&63)+128);
if($num<32768)
return chr(($num>>12)+224).chr((($num>>6)&63)+128)
.chr(($num&63)+128);
if($num<2097152)
return chr(($num>>18)+240).chr((($num>>12)&63)+128)
.chr((($num>>6)&63)+128).chr(($num&63)+128);
return '';
}
function unescape($strIn, $iconv_to = 'UTF-8') {
$strOut = '';
$iPos = 0;
$len = strlen ($strIn);
while ($iPos < $len) {
$charAt = substr ($strIn, $iPos, 1);
if ($charAt == '%') {
$iPos++;
$charAt = substr ($strIn, $iPos, 1);
if ($charAt == 'u') {
// Unicode character
$iPos++;
$unicodeHexVal = substr ($strIn, $iPos, 4);
$unicode = hexdec ($unicodeHexVal);
$strOut .= code2utf($unicode);
$iPos += 4;
}
else {
// Escaped ascii character
$hexVal = substr ($strIn, $iPos, 2);
if (hexdec($hexVal) > 127) {
// Convert to Unicode
$strOut .= code2utf(hexdec ($hexVal));
}
else {
$strOut .= chr (hexdec ($hexVal));
}
$iPos += 2;
}
}
else {
$strOut .= $charAt;
$iPos++;
}
}
if ($iconv_to != "UTF-8") {
$strOut = iconv("UTF-8", $iconv_to, $strOut);
}
return $strOut;
}

spam at soiland dot no (2005-04-05 17:45:21)

Matt Johnson (2004-12-25 16:49:46)

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.

caribe at flash-brasil dot com dot br (2003-10-13 13:55:36)

(2003-10-09 08:17:34)

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.

tomas at penajaca dot com dot br (2003-07-20 23:14:13)

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");
}

regindk at hotmail dot com (2003-04-23 18:00:35)

bellani at upgrade4 dot it (2003-03-11 10:12:54)

smolniy at mtu dot ru (2003-02-07 14:42:41)

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

igjav at cesga dot es (2002-05-16 11:48:58)

易百教程