用户
 找回密码
 入住 CI 中国社区
搜索
查看: 1981|回复: 5
收起左侧

[讨论/交流] 2.1.4版本URI类这个是否算BUG

[复制链接]
发表于 2014-2-23 18:31:43 | 显示全部楼层 |阅读模式
本帖最后由 昨夜渡轮 于 2014-2-23 18:34 编辑

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

该类中的方法function _fetch_uri_string()其中执行这段代码时:
PHP复制代码
 
// 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()发现最后这段代码:
PHP复制代码
 
return str_replace(array('//', '../'), '/', trim($uri, '/'));
 
复制代码

替换掉了“/”斜杠。

如果该类中的方法function _fetch_uri_string()其中执行这段代码时:
PHP复制代码
 
// 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()其中执行这段代码时:
PHP复制代码
 
// 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)这二个方法中这段代码:
PHP复制代码
 
$uri =        $CFG->item('base_url').
                $CFG->item('index_page').
                $URI->uri_string;
 
复制代码

缓存文件名$uri,当URI类中的方法function _fetch_uri_string()其中执行这段代码且满足条件时:
PHP复制代码
 
// 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):
PHP复制代码
 
// 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[0];
                if (isset($parts[1]))
                {
                        $_SERVER['QUERY_STRING'] = $parts[1];
                        parse_str($_SERVER['QUERY_STRING'], $_GET);
                }
                else
                {
                        $_SERVER['QUERY_STRING'] = '';
                        $_GET = array();
                }
 
 
复制代码


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

同时对于CI缓存目录考虑性能问题我打算用如下方法:
PHP复制代码
 
crc32($uri)%1000; //用取余的方法来生成1000个目录分布存储
 
复制代码

这样应该能够满足一般网站的访问量了吧?
 楼主| 发表于 2014-2-25 09:08:18 CI中国手机版 | 显示全部楼层
顶起来,怎没反应?
发表于 2014-2-25 10:18:47 | 显示全部楼层
说实在的,这个问题的正文那么长,我实在是没看下去的冲动
 楼主| 发表于 2014-2-25 16:33:19 CI中国手机版 | 显示全部楼层
我只是想将问题讲出来,也希望得到HEX和大家确认。
发表于 2014-2-25 17:05:44 | 显示全部楼层
缓存的好像是不带参数的,也就是只能缓存http://www.ex.com/index.php/welcome/index  不管带不带参数都读取的该地址,如果要实现带参数就重写吧, 你都调试的这么清楚了,应该没什么问题。
 楼主| 发表于 2014-2-25 20:58:27 CI中国手机版 | 显示全部楼层
嗯实现这个确实没有问题,只是可能有人不知道这回事,使用当中确实有人用这类似地址,官方可以考虑改进改进。

本版积分规则