CodeIgniter URL设计严重缺陷
CodeIgniter 号称生成的 URL 非常干净而且是对搜索引擎友好化的。不同于标准的“字符串查询”方法1 example.com/news/article/345
2example.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函数如下:
function segment($n, $no_result = FALSE)
{
return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
}
扩展segment如下
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函数原型
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
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里
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 echosite_url('/文章/查看/文章ID');?>
然后根据enable_query_strings环境生成以下
index.php/文章/查看/文章ID
index.php?c=文章&m=查看&id=文章ID 佩服楼主的钻研精神~
不过,我一般采用 URI 分段和 GET 传参结合的方式,就不存在一会儿用 $_GET 一会儿用 segment 的问题了。 抱歉,代码有些乱 Hex 发表于 2012-2-10 16:35 static/image/common/back.gif
佩服楼主的钻研精神~
不过,我一般采用 URI 分段和 GET 传参结合的方式,就不存在一会儿用 $_GET 一会儿用 ...
URI 分段是很好,但是在论坛里搜索一下URL,都是什么香港主机啊这那的不支持各URL,所以统一URL一定可以在各种虚拟主机下生存的方法(只需更改config.php的配置,可惜SEO不好友:lol), sdink 发表于 2012-2-10 16:36 static/image/common/back.gif
抱歉,代码有些乱
我给你修改好代码格式了~呵呵 Hex 发表于 2012-2-10 17:26 static/image/common/back.gif
我给你修改好代码格式了~呵呵
十分感谢 路过看高手! 309090518 发表于 2012-2-10 18:28 static/image/common/back.gif
路过看高手!
今天无意发现的,俺是个菜鸟 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 07:19 static/image/common/back.gif
这个是搜索引擎友好化了的URL?
能这么说的!真拜服拜服!
你是中国人么?上下文会联系么?CodeIgniter 号称生成的 URL 非常干净而且是对搜索引擎友好化的。已有句号。生成的 URL 非常干净而且是对搜索引擎友好化的。是CI的号称,不是我说的,与下文无关。1 example.com/news/article/345
2example.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 ),那么我想问,开发人员这是干什么,换个环境改来改去的,何必?所以一个成熟的产品不管你环境有何变动,不会影响整个项目运作。精髓在于任何环境下,我只需要改我的配置,而不是去改项目中的主体部分。