pillar 发表于 2008-11-6 15:58:11

我也谈一下URI里面传送中文问题

之前想要做一个搜索的东西,需要把关键词放到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采用的是固定的”/^+$/i“。这样,即便在$config['permitted_uri_chars']里面设置了中文的匹配条件,也会在Input.php层被卡掉。
       我的解决方法是:扩展Input类。

   function _clean_input_keys($str)
    {
         if ( ! preg_match("/^+$/i", $str))
         {
             exit('Disallowed Key Characters.');
         }
      return $str;
    }
修改成
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

Hex 发表于 2008-11-6 17:27:13

讲的非常详细,可以说是深入浅出了。

pillar 发表于 2008-11-6 21:08:01

哈哈。我的处女精华帖。多谢Hex~

le_el 发表于 2009-1-13 10:11:24

Pillar 恭喜你~~~~!:victory: :kiss:

ambo 发表于 2009-4-19 23:18:01

不错不错

Hex 发表于 2009-4-29 17:46:04

请注意楼主解决方案的 CI 版本,新版可能不一样了。

fanxuan 发表于 2011-2-8 11:55:10

很不错,写得简单,用起来实用。。。
页: [1]
查看完整版本: 我也谈一下URI里面传送中文问题