转载自:http://hi.baidu.com/micropoor

//2011-11-18 星期五 
//知识点讲解:urlencode
//返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。此编码与 WWW 表单 POST 数据的编码方式是一样的,同时与 application/x-www-form-urlencoded 的媒体类型编码方式一样。由于历史原因,此编码在将空格编码为加号(+)方面与 RFC1738 编码不同。
//PHP 手册中,urldecode 函数原文引用:
The superglobals $_GET and $_REQUEST are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results. 
原型:string urldecode ( string $str )
urldecode() 例子
//Micropoor.php  部分代码
//安全规范代码示例:
<?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])), "\n";
    $i++;
}
?>
 
//Micropoor.php  部分代码
$str1=urlencode("Micropoor"); //$str1的值是%4D%69%63%72%6F%70%6F%6F%72
$str2=urldecode($str1); //$str2的值就是“Micropoor”
 
//新闻也跑题:
URLEncode:是指针对网页url中的中文字符的一种编码转化方式,最常见的就是Baidu、Google等搜索引擎中输入中文查询时候,生成经过 Encode过的网页URL。
URLEncode的方式一般有两种一种是传统的基于GB2312的Encode(Baidu、Yisou等使用),一种是 基于UTF-8的Encode(Google,Yahoo等使用)。本工具分别实现两种方式的Encode与Decode。 
中文 -> GB2312的Encode -> %D6%D0%CE%C4 
中文 -> UTF-8的Encode -> %E4%B8%AD%E6%96%87
 
urlencode和rawurlencode的区别: 
urlencode 将空格则编码为加号(+) 
rawurlencode 将空格则编码为加号(%20)
如果要使用UTF-8的Encode,有两种方法: 
一、将文件存为UTF-8文件,直接使用urlencode、rawurlencode即可。 
二、使用mb_convert_encoding函数。 
 
//历史回顾:
//Discuz SQL
//程序员思维
//..略
foreach($_POST as $k => $v) { 
$value = urldecode($v); 
$this->setParameter($k, $value); 

单引号被 urlencode 两次以后是 %2527,然后 POST,PHP 内部在生成全局变量 $_POST 的时候会先 urldecode,得到 %27,然后 PHP 会检查 Magic Quotes 的设置,但是无论是否开启 Magic Quotes,%27 都不会被 addslashes,因为这时根本没有单引号。但是这时如果你在 PHP 代码中画蛇添足的加上 urldecode,%27就变成单引号了,然后SQL出现。 
 
//实战源码审核---引用毅心毅意
//程序员思维
function onsearch() {
        $navtitle = '搜索问题';
        $qstatus = $status = $this->get[2];
        (3 == $status) && ($qstatus = "1,2");
        @$word = urldecode($this->post['word'] ? $this->post['word'] : $this->get[3]);//看这里..如果你get %27 他会过滤.. 如果你get %2527 他会处理成%27.。不会产生注入..但是如果post %27呢 。。成功绕过过滤 
        empty($word) && $this->message("搜索关键!", 'BACK');
        $encodeword = urlencode($word);
 
        @$page = max(1, intval($this->get[4]));
        $pagesize = $this->setting['list_default']; 
        $startindex = ($page - 1) * $pagesize; //每页面显示25条
        $rownum = $_ENV['question']->search_title_num($word, $qstatus); //获取总的记录数  
        $questionlist = $_ENV['question']->search_title($word, $qstatus, $startindex, $pagesize); //问题列表数据  
        $departstr = page($rownum, $pagesize, $page, "question/search/$status/$word"); //得到分页字符串
       
        $this->load('setting');
                $wordslist = unserialize($this->setting['hot_words']);
        
        include template('search');;
    }
//我们的思维
利用方式:post 编码的sql注入语句
 
//知识拓展:
//JS实现PHP的urlencode函数
 function URLEncode (clearString) {
   var output = '';
   var x = 0;
   clearString = clearString.toString();
   var regex = /(^[a-zA-Z0-9-_.]*)/;
   while (x < clearString.length) {
     var match = regex.exec(clearString.substr(x));
     if (match != null && match.length > 1 && match[1] != '') {
         output += match[1];
       x += match[1].length;
     } else {
       if (clearString.substr(x, 1) == ' ') {
         //原文在此用 clearString[x] == ' ' 做判断, 但ie不支持把字符串当作数组来访问, 
         //修改后两种浏览器都可兼容 
         output += '+';
       }
       else {
         var charCode = clearString.charCodeAt(x);
         var hexVal = charCode.toString(16);
         output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase();
       }
       x++;
     }
   }
   return output;
 }

    结论:最好的教科书便是XXX手册