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

[讨论/交流] CodeIgniter URL设计严重缺陷

  [复制链接]
发表于 2012-2-10 14:43:55 | 显示全部楼层 |阅读模式
CodeIgniter 号称生成的 URL 非常干净而且是对搜索引擎友好化的。不同于标准的“字符串查询”方法
1 example.com/news/article/345
2  example.com?c=news&m=article&id=345


上面是于enable_query_strings在不同环境下的URL
如果我要获取上面URL里的345,当然用CI的$this->uri->segment ( 3 ),PHP自身的$_GET一样可以,
但是,我现在要做一个项目,不因为enable_query_strings的改变一会儿$_GET一会儿$this->uri->segment ( 3 )的,
在说没有病一会儿判断$this->uri->segment ( 3 )一会儿判断$_GET的,没必要吧
那么我想在整个项目里只用$this->uri->segment ( 3 ),此时有只扩展segment
文件 system/core/URL.php
segment函数如下:
PHP复制代码
function segment($n, $no_result = FALSE)
        {
                return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
        }
复制代码

        
扩展segment如下
PHP复制代码
function segment($n, $no_result = FALSE) {
                if ($this->config->item ( 'enable_query_strings' ) == FALSE) {
                        return (! isset ( $this->segments [$n] )) ? $no_result : $this->segments [$n];
                } else {
                        $getarray = array ('1' => 'c', 2 => 'm', '3' => 'id', '4' => 'name' );
                        $get = $_GET;
                        return (! isset ( $get [$getarray [$n]] )) ? $no_result : $get [$getarray [$n]];
                }
        }
复制代码

那么仅仅扩展segment是不够的.在扩展site_url,site_url是CI核心site_url,不是辅助函数的site_url
文件 system/core/Config.php
site_url函数原型
PHP复制代码
function site_url($uri = '')
        {
                if ($uri == '')
                {
                        return $this->slash_item('base_url').$this->item('index_page');
                }
                if ($this->item('enable_query_strings') == FALSE)
                {
                        $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
                        return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
                }
                else
                {
                        return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri);
                }
        }
复制代码

扩展后的site_url
PHP复制代码
function site_url($uri = '') {
                if ($uri == '') {
                        return $this->slash_item ( 'base_url' ) . $this->item ( 'index_page' );
                }
                                if ($this->item ( 'enable_query_strings' ) == FALSE) {
                        $suffix = ($this->item ( 'url_suffix' ) == FALSE) ? '' : $this->item ( 'url_suffix' );
                        return $this->slash_item ( 'base_url' ) . $this->slash_item ( 'index_page' ) . $this->_uri_string ( $uri ) . $suffix;
                } else {
                        $str = $this->_uri_string ( $uri );
                        $str = 'c=' . $str;
                        $f = stripos ( $str, '/' );
                        if ($f) {
                                $as = substr ( $str, 0, $f );
                                $fs = '&m=' . substr ( $str, $f + 1 );
                                $str = $as . $fs;
                        }
                        $i = stripos ( $str, '/' );
                        if ($i) {
                                $bs = substr ( $str, 0, $i );
                                $is = '&id=' . substr ( $str, $i + 1 );
                                $str = $bs . $is;
                        }
                        $n = stripos ( $str, '/' );
                        if ($n) {
                                $cs = substr ( $str, 0, $n );
                                $ns = '&name=' . substr ( $str, $n + 1 );
                                $str = $cs . $ns;
                        }
                        //$str = str_replace ( '?', '&', $str );
                       return $this->slash_item ( 'base_url' ) . $this->item ( 'index_page' ) . '?' . $this->_uri_string ( $str );
                }
        }
复制代码

此时$this->uri->segment ( 3 )就可以通用了
后记:
为了更强大.我们应该在配置文件cofnig里定义一个这样
$config['XXXX']='index.php|c|m|i|f|p';
在URL.hph里
PHP复制代码
function segment($n, $no_result = FALSE) {
                if ($this->config->item ( 'enable_query_strings' ) == FALSE) {
                        return (! isset ( $this->segments [$n] )) ? $no_result : $this->segments [$n];
                }
                $getarray = explode ('|',$this->config->item ( 'XXXX' ));
                $get = $_GET;
                return (! isset ( $get [$getarray [$n]] )) ? $no_result : $get [$getarray [$n]];
        }
复制代码

site_url自己去更强大吧

一般用的时候都是加载辅助函数site_url,然后在视图里就
PHP复制代码
<?php echo  site_url('/文章/查看/文章ID');?>
复制代码

然后根据enable_query_strings环境生成以下

index.php/文章/查看/文章ID
index.php?c=文章&m=查看&id=文章ID

评分

参与人数 1威望 +5 收起 理由
Hex + 5 很不错

查看全部评分

发表于 2012-2-10 16:35:20 | 显示全部楼层
佩服楼主的钻研精神~

不过,我一般采用 URI 分段和 GET 传参结合的方式,就不存在一会儿用 $_GET 一会儿用 segment 的问题了。
 楼主| 发表于 2012-2-10 16:36:21 | 显示全部楼层
抱歉,代码有些乱
 楼主| 发表于 2012-2-10 17:10:05 | 显示全部楼层
Hex 发表于 2012-2-10 16:35
佩服楼主的钻研精神~

不过,我一般采用 URI 分段和 GET 传参结合的方式,就不存在一会儿用 $_GET 一会儿用 ...

URI 分段是很好,但是在论坛里搜索一下URL,都是什么香港主机啊这那的不支持各URL,所以统一URL一定可以在各种虚拟主机下生存的方法(只需更改config.php的配置,可惜SEO不好友),
发表于 2012-2-10 17:26:09 | 显示全部楼层
sdink 发表于 2012-2-10 16:36
抱歉,代码有些乱

我给你修改好代码格式了~呵呵
 楼主| 发表于 2012-2-10 18:00:16 | 显示全部楼层
Hex 发表于 2012-2-10 17:26
我给你修改好代码格式了~呵呵

十分感谢
发表于 2012-2-10 18:28:05 | 显示全部楼层
路过看高手!
 楼主| 发表于 2012-2-10 21:30:01 | 显示全部楼层
309090518 发表于 2012-2-10 18:28
路过看高手!

今天无意发现的,俺是个菜鸟
发表于 2012-2-11 07:19:52 | 显示全部楼层
example.com?c=news&m=article&id=345

这个是搜索引擎友好化了的URL?

能这么说的!真拜服拜服!

这些URL正是CodeIgniter认为不友善,不干净的URL!


example.com/news/article/345

才是SEO友善的URL!

这些码是让CodeIgniter去兼容、生成古代搜索引擎不友好的URL。


作为个人喜好,这类不自然的URL是可以的,因外行人家看不懂,这正是不友好之处。SEO正是要远离这些不自然的URL!

 楼主| 发表于 2012-2-11 09:12:54 | 显示全部楼层
燃雲 发表于 2012-2-11 07:19
这个是搜索引擎友好化了的URL?

能这么说的!真拜服拜服!

你是中国人么?上下文会联系么?
CodeIgniter 号称生成的 URL 非常干净而且是对搜索引擎友好化的。
已有句号。
生成的 URL 非常干净而且是对搜索引擎友好化的。
是CI的号称,不是我说的,与下文无关。
1 example.com/news/article/345
2  example.com?c=news&m=article&id=345
下面一句我是这么写的
上面是于enable_query_strings在不同环境下的URL
,我写的这些很简单,就是一个大项目时我会多用
$this->uri->segment ( 3 ),$this->uri->segment (4),$this->uri->segment ( 5 )
等等来取值,但是在有的虚拟主机里不支持伪静态,也不支持index.php/这样的,他认为index.php是一个目录,所以这个时候你只能用如
example.com?c=news&m=article&id=345
这样的方式,但是我已经在我的整个项目里用
$this->uri->segment ( 3 ),$this->uri->segment (4),$this->uri->segment ( 5 )
等,我没必要又在整个项目里改成$_GET['c'],$_GET['M'],$_GET['id'],如果改,那么若有一天你换个环境,你的环境支持伪静态,你已想把URL改成
example.com/news/article/345
,然后你又把整个项目里的
$_GET['c'],$_GET['M'],$_GET['id']
改成
$this->uri->segment ( 3 ),$this->uri->segment (4),$this->uri->segment ( 5 )
,那么我想问,开发人员这是干什么,换个环境改来改去的,何必?所以一个成熟的产品不管你环境有何变动,不会影响整个项目运作。精髓在于任何环境下,我只需要改我的配置,而不是去改项目中的主体部分。

本版积分规则