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