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

[URL] 关于show_404页面访问CI资源的问题

[复制链接]
发表于 2011-8-25 15:30:08 | 显示全部楼层 |阅读模式
本帖最后由 yuzhigang5460 于 2011-8-25 16:48 编辑

CI默认的404页面在application/errors/show_404.php下,当访问控制器类或方法不存在时将会路由到此处,但我现在有一个简单的需求,想在这个404页面上加一个返回到home主页的链接,那么该怎么办呢?

你可能首先想到的是加一句话即可:
PHP复制代码
<?php echo anchor('', '回到首页');?>
复制代码


那么这样做行不行呢,比如我们访问http://www.test.com/index.php/blog/view,现在我们分两种情况来讨论:
1. 你的网站根本不存在blog控制器,即不存在这个类;
2. 你的网站存在这个blog控制器,但不在view这个方法;

当是第二种情况时,使用
PHP复制代码
<?php echo anchor('', '回到首页');?>
复制代码
没有问题;
但是第一种情况时,这个方法就不行了。

实际上第一种情况在用户访问网站时也存在的,当用户误入404页面后返回到主页的需求也是存在的。但为什么第一种情况时访问CI资源不行呢?我们可以看源代码:
PHP复制代码
 
    $RTR =& load_class('Router', 'core');
    $RTR->_set_routing();
    ...........
    function _validate_request($segments)
 
   .........
  $CI = new $class();
 
复制代码

可以看到在CI对象还没存在的时候,我们就有误入404的可能,大部分CI的资源,如helper,library等都是在new CI的时候创建的,所以此时根本无法使用这些helper来返回主页。

那如果使用routers的自定义404页面呢?
PHP复制代码
$route['404_override'] = 'error/myerror';
复制代码

然后自己写一个控制器,加上方法。【更新:此时是可以使用CI对象的,被重新路由到自定义404页面,如果自定义页面存在的话,否则还是会被带到系统默认的show_404页面,依旧使用不了CI对象】

那么,使用htaccess的ErrorDocument呢,原则上CI对进入了index.php的一切url地址通吃,不存在errorDocument,所以无法处理在CI内出现的错误控制器情况。

【以上理解有误的地方已经被我修改了】
{:soso__433253175740619224_4:}

评分

参与人数 1威望 +5 收起 理由
Hex + 5 钻研精神赞一个!

查看全部评分

 楼主| 发表于 2011-8-25 16:37:11 | 显示全部楼层
本帖最后由 yuzhigang5460 于 2011-8-25 16:40 编辑

各位同学抱歉,是我自己的理解有误,会让大家产生误解,实属自己研究不够深入。

后仔细查看源代码,实际上当CodeIgniter.php中调用$RTR->_set_routing();时便启动了对url的检查,检查由Router.php中的_validate_request()函数执行,执行发现url不存时即可路由到自定义的404页面,此时相对于新生成了一个ci对象,所以自定义404页面是可以访问ci资源的;

但系统默认的的404页面,始终访问不了ci资源,因为它是被直接渲染出来的,来没来得及生成CI对象。

这个帖子主要的结论有2个:
1. 系统默认的404页面不能访问CI对象;
2. 自定义404页面可以访问CI对象(汗_!);

误导大家了,抱歉。
发表于 2011-8-25 17:19:10 | 显示全部楼层

评分

参与人数 1威望 -3 收起 理由
Hex -3 违反版规:纯表情回复

查看全部评分

发表于 2011-8-27 11:58:43 | 显示全部楼层
首先,楼主的钻研精神值得大家学习。
其次,对于CI来说,可以使用Hook和“扩展核心类”,来彻底影响 CI 的核心初始化逻辑。
感觉上 CI 每个部分都可以不修改源码来定制,太强大了,呵呵
发表于 2011-9-15 13:42:50 | 显示全部楼层
亲你的结论:
1. 系统默认的404页面不能访问CI对象;
2. 自定义404页面可以访问CI对象(汗_!);
有点不苟同
1. 你的网站根本不存在blog控制器,即不存在这个类;
2. 你的网站存在这个blog控制器,但不在view这个方法;
当1的情况是
router _validate_request 是直接show_404这里的error_404页面是不访问系统资源的
当2的情况是
是在Call the requested method触发的,实际已经调用Ci资源
如果你想请求资源的话,可以把function写到common.php里面

本版积分规则