PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

urlencode> <rawurlencode
Last updated: Fri, 10 Oct 2008

view this page in

urldecode

(PHP 4, PHP 5)

urldecodeDecodes URL-encoded string

Description

string urldecode ( string $str )

Decodes any %## encoding in the given string.

Parameters

str

The string to be decoded.

Return Values

Returns the decoded string.

Examples

Example #1 urldecode() example

<?php
$a 
explode('&'$QUERY_STRING);
$i 0;
while (
$i count($a)) {
    
$b split('='$a[$i]);
    echo 
'Value for parameter 'htmlspecialchars(urldecode($b[0])),
         
' is 'htmlspecialchars(urldecode($b[1])), "<br />\n";
    
$i++;
}
?>

Notes

Warning

The superglobals $_GET and $_REQUEST are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results.



urlencode> <rawurlencode
Last updated: Fri, 10 Oct 2008
 
add a note add a note User Contributed Notes
urldecode
gisli_viglundsson at hotmail dot com
30-Jul-2008 06:34
How do I make %2F to become /

?
peter at lofas dot se
17-Jul-2008 03:40
ignacio dot javier dot igjav at gmail dot com

I think you need to add
<?php
elseif($charAt == '+') {
      
$decodedStr .= " ";
      
$pos++;
    }
?>
to your  crossUrlDecode function for it to support cases with spaces in the encoded sentence.
ignacio dot javier dot igjav at gmail dot com
03-Jul-2008 07:04
/*
Original source has lost, seems due to a utf8-ascii-utf8 translation, 2 relevant characters in 2 lines of the function, character à in lines 8 and 21. This is the correct version:
*/

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;
}
Jan Vratny
12-Jun-2008 08:09
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
04-Apr-2008 03:11
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
05-Dec-2007 06:58
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
brainstorm<at>brainstorm.name
12-Apr-2007 07:32
Ok, all looks like, but what to do if you use another encoding with urldecode?

Here is my solution - I have towork with project in windows-1251 encoding

$textu = Misc_func::getRequestParam('text', '');
if($_SERVER["REQUEST_METHOD"] == 'GET'){
    $text = iconv('utf-8', 'cp1251', urldecode($textu) );
}
pedantic at hotmail co jp
17-Nov-2006 12:22
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 + 2, 4));
     
$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
06-Oct-2006 06:56
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
19-Aug-2006 04:05
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
19-May-2006 03:02
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
20-Apr-2006 12:40
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
08-Mar-2006 05:20
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
06-Apr-2005 08:45
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" />.
Matt Johnson
26-Dec-2004 08:49
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
14-Oct-2003 04:55
To allow urldecode to work with Brazilian characters as ç ã ó and other just place this header command :

header('Content-type: text/html; charset=UTF-8');
09-Oct-2003 11:17
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
21-Jul-2003 02:14
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
24-Apr-2003 09:00
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);
bellani at upgrade4 dot it
12-Mar-2003 02:12
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!!
smolniy at mtu dot ru
08-Feb-2003 06:42
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
17-May-2002 02:48
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;
}

urlencode> <rawurlencode
Last updated: Fri, 10 Oct 2008
 
 
show source | credits | sitemap | contact | advertising | mirror sites