昨夜渡轮 发表于 2014-2-23 18:31:43

2.1.4版本URI类这个是否算BUG

本帖最后由 昨夜渡轮 于 2014-2-23 18:34 编辑

当我们访问如:http://www.ex.com/index.php/welcome/index?page=8

该类中的方法function _fetch_uri_string()其中执行这段代码时:

// Let's try the REQUEST_URI first, this will work in most situations
if ($uri = $this->_detect_uri())
{
      $this->_set_uri_string($uri);
      return;
}


我们得到的$this->uri->uri_string是这样的:welcome/index

查看了私有方法private function _detect_uri()发现最后这段代码:

return str_replace(array('//', '../'), '/', trim($uri, '/'));

替换掉了“/”斜杠。

如果该类中的方法function _fetch_uri_string()其中执行这段代码时:

// Is there a PATH_INFO variable?
// Note: some servers seem to have trouble with getenv() so we'll test it two ways
$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path, '/') != '' && $path != "/".SELF)
{
      $this->_set_uri_string($path);
      return;
}


我们得到的$this->uri->uri_string是这样的:/welcome/index

如果该类中的方法function _fetch_uri_string()其中执行这段代码时:

// No PATH_INFO?... What about QUERY_STRING?
$path =(isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') != '')
{
      $this->_set_uri_string($path);
      return;
}


我们得到的$this->uri->uri_string是这样的:page=8

同时这里涉及到CI自带的文件缓存OUTPUT类中的function _write_cache($output)和function _display_cache(&$CFG, &$URI)这二个方法中这段代码:

$uri =      $CFG->item('base_url').
                $CFG->item('index_page').
                $URI->uri_string;

缓存文件名$uri,当URI类中的方法function _fetch_uri_string()其中执行这段代码且满足条件时:

// Let's try the REQUEST_URI first, this will work in most situations
if ($uri = $this->_detect_uri())
{
      $this->_set_uri_string($uri);
      return;
}

当我们访问如:
http://www.ex.com/index.php/welcome/index?page=1
http://www.ex.com/index.php/welcome/index?page=2
http://www.ex.com/index.php/welcome/index?page=3
http://www.ex.com/index.php/welcome/index?page=4
http://www.ex.com/index.php/welcome/index?page=5
这样的网址时,缓存文件名$uri一直都是md5('http://www.ex.com/index.php/welcome/index')导致访问多个不同的页面只能用同一文件名来缓存,导致缓存无效。
为什么URI类中private function _detect_uri()方法要用这段代码去掉$_SERVER['QUERY_STRING']部份(page=8):

// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
                // URI is found, and also fixes the QUERY_STRING server var and $_GET array.
                if (strncmp($uri, '?/', 2) === 0)
                {
                        $uri = substr($uri, 2);
                }
               
                $parts = preg_split('#\?#i', $uri, 2);
                $uri = $parts;
                if (isset($parts))
                {
                        $_SERVER['QUERY_STRING'] = $parts;
                        parse_str($_SERVER['QUERY_STRING'], $_GET);
                }
                else
                {
                        $_SERVER['QUERY_STRING'] = '';
                        $_GET = array();
                }



大家有什么好的建议?请各位老大指点。

同时对于CI缓存目录考虑性能问题我打算用如下方法:

crc32($uri)%1000; //用取余的方法来生成1000个目录分布存储

这样应该能够满足一般网站的访问量了吧?

昨夜渡轮 发表于 2014-2-25 09:08:18

顶起来,怎没反应?

kissgxd 发表于 2014-2-25 10:18:47

说实在的,这个问题的正文那么长,我实在是没看下去的冲动

昨夜渡轮 发表于 2014-2-25 16:33:19

我只是想将问题讲出来,也希望得到HEX和大家确认。

Bobby 发表于 2014-2-25 17:05:44

缓存的好像是不带参数的,也就是只能缓存http://www.ex.com/index.php/welcome/index不管带不带参数都读取的该地址,如果要实现带参数就重写吧, 你都调试的这么清楚了,应该没什么问题。

昨夜渡轮 发表于 2014-2-25 20:58:27

嗯实现这个确实没有问题,只是可能有人不知道这回事,使用当中确实有人用这类似地址,官方可以考虑改进改进。
页: [1]
查看完整版本: 2.1.4版本URI类这个是否算BUG