from : http://codeigniter.org.cn/forums/thread-1224-1-1.html

参考URL:http://codeigniter.com/forums/viewthread/54019/

之前想要做一个搜索的东西,需要把关键词放到URL上面,对用户更加的友好,而且我感觉这样也容易做分页,避免不断的post和用会话保存关键词。
比如下面的路径:
       http://www.example.com/search/name/我是中文
       但是一直报错:Disallowed Key Characters.
       之前一直以为是system/library/URI.php的问题。不断的去修改系统的$config['permitted_uri_chars'] = 'a-z A-Z 0-9~%.:_\-';和URI.php里面的_filter_uri($str)函数。也参照了之前几位仁兄的经验,结果还是没有成功。
       无奈之下,搜索这句报错信息的来源。结果发现是在system/library/URI.php里面的_clean_input_keys($str)这个函数。因为中文的编码在这个地方没有通过正则表达式的匹配,只能被无情的挂掉。
       现在看来,CI过滤URI中的字符有两道防线,第一道防线,是Input.php类里面的_clean_input_keys($str)函数,通过正则匹配,及时卡掉非法字符,第二道防线是URI.php里面的_filter_uri($str),通过系统设定的$config['permitted_uri_chars']来进行正则的匹配。卡掉非法的字符。但是我又感到了CI框架的一个缺陷。就是Input.php和URI.php里面的过滤函数各为其主,采用不同的正则表达式进行匹配,URI.php里面采用的是正统的$config['permitted_uri_chars'],Input.php采用的是固定的”/^[a-z0-9:_\/-]+$/i“。这样,即便在$config['permitted_uri_chars']里面设置了中文的匹配条件,也会在Input.php层被卡掉。
       我的解决方法是:扩展Input类。
PHP
function _clean_input_keys($str)
    {
         if ( ! preg_match("/^[a-z0-9:_/-]+$/i", $str))
         {
             exit('Disallowed Key Characters.');
         }
        return $str;
    }
复制代码
修改成
PHP
function _clean_input_keys($str)
    {
         $config = &get_config('config');
        if ( ! preg_match("/^[".$config['permitted_uri_chars']."]+$/i", rawurlencode($str)))
        {
            exit('Disallowed Key Characters.');
        }
        return $str;
    }
复制代码
这样就能够在URI传送中文了。我的CI版本是1.6.3