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

分析CI的错误处理(404等)

[复制链接]
发表于 2008-9-23 01:22:40 | 显示全部楼层 |阅读模式
前些天群里有位朋友询问关于CI如何设置404的问题,晚上仔细研究了一下CI的异常处理模块,现总结如下:
大家都知道CI处理错误的函数有三个,分别是:show_error('消息')、show_404('页面')
log_message('级别','消息')。
  • CI处理异常的流程:
       首先,CI在codeigniter.php的38行处加载common文件
       require(BASEPATH.'codeigniter/Common'.EXT);
       我们试着分析一下Common.php文件,此文件的187行开始,直到文档末尾,定义了错误处理函数。
PHP复制代码
 
function show_error($message)
{
//调用异常处理文件
        $error =& load_class('Exceptions');
//异常处理文件中的show_error函数
        echo $error->show_error('An Error Was Encountered', $message);
        exit;
}
 
function show_404($page = '')
{
//调用异常处理文件
$error =& load_class('Exceptions');
//异常处理文件中的show_404函数
$error->show_404($page);
exit;
}
 
function log_message($level = 'error', $message, $php_error = FALSE)
{
static $LOG;
//获取CI配置项
$config =& get_config();
if ($config['log_threshold'] == 0)
{
  return;
}
//调用log.php类文件
$LOG =& load_class('Log');
//log.php类文件中的write_log函数
$LOG->write_log($level, $message, $php_error);
}
 
复制代码


从以上代码中,我们可以发现,CI的这些错误处理函数都调用了同一个文件,那就是Exceptions.php,这个文件位于/system/library/目录下,接下来,我们就分析一下这个文件

function show_404($page = '')
PHP复制代码
 
function show_404($page = '')
//404处理页面
{
//定义两个变量
  $heading = "404 Page Not Found";
  $message = "The page you requested was not found.";
//写入日志
  log_message('error', '404 Page Not Found --> '.$page);
//调用show_error函数,并将之前定义的$heading和$message变量传递过去
//这句中的第三个参数是关键error_404,这是模板文件名
//如果想更改,就得更改这个参数,我们可以把error_404替换为你的模板文件,或者将它变为
//echo $this->show_error($heading, $message,$page);
//这个$page为模板文件名
  echo $this->show_error($heading, $message, 'error_404');
  exit;
}
 
复制代码


function show_error($heading, $message, $template = 'error_general')
PHP复制代码
 
//这才是异常处理的核心
function show_error($heading, $message, $template = 'error_general')
{
//简单过滤一下传递过来的变量的值
  $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
  if (ob_get_level() > $this->ob_level + 1)
  {
   ob_end_flush();
  }
  ob_start();
//这里就是模板文件,注意:CI所有的异常处理模板文件都在errors目录下
  include(APPPATH.'errors/'.$template.EXT);
  $buffer = ob_get_contents();
  ob_end_clean();
  return $buffer;
}
 
复制代码


function show_php_error($severity, $message, $filepath, $line)
PHP复制代码
 
//这个函数和上面的函数大体差不多
function show_php_error($severity, $message, $filepath, $line)
{
  $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
 
  $filepath = str_replace("\\", "/", $filepath);
 
  // For safety reasons we do not show the full file path
  if (FALSE !== strpos($filepath, '/'))
  {
   $x = explode('/', $filepath);
   $filepath = $x[count($x)-2].'/'.end($x);
  }
 
  if (ob_get_level() > $this->ob_level + 1)
  {
   ob_end_flush();
  }
  ob_start();
  include(APPPATH.'errors/error_php'.EXT);
  $buffer = ob_get_contents();
  ob_end_clean();
  echo $buffer;
}
 
复制代码


最后附上我更改后的show_error函数
PHP复制代码
 
function show_404($page = '')
{
  $heading = "404 Page Not Found";
  $message = "The page you requested was not found.";
  log_message('error', '404 Page Not Found --> '.$page);
  if(!$page) {
//如果$page为空,则显示默认404错误页面
   echo $this->show_error($heading, $message, 'error_404');
  }
  else {
//如果$page不为空,则显示定义的404错误页面
   echo $this->show_error($heading, $message, $page);
  }
  exit;
}
 
复制代码

关于调用:
调用时可以这样:show_404()或show_404('404')

这个修改方法同样适用于show_error函数,我们看一下修改后的show_error函数:
PHP复制代码
 
function show_error($heading, $message, $template = '')
 {
  $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
  if (ob_get_level() > $this->ob_level + 1)
  {
   ob_end_flush();
  }
  if(!$template) {
   $template='error_general';
  }
  ob_start();
  include(APPPATH.'errors/'.$template.EXT);
  $buffer = ob_get_contents();
  ob_end_clean();
  return $buffer;
 }
 
 
复制代码


而调用函数也相应得变为
log_message('级别', '消息','模板')注意:第三个参数可为空

大体就是这样,如果我的分析有错误,请各位网友跟贴指正,谢谢

[ 本帖最后由 analyzer 于 2008-9-23 02:17 编辑 ]

评分

参与人数 1威望 +5 收起 理由
Hex + 5 原创内容

查看全部评分

发表于 2008-9-23 01:53:51 | 显示全部楼层
学习一下
发表于 2008-9-23 08:43:21 | 显示全部楼层
对CI比较深入了,研究源码了。支持一下。
发表于 2008-9-23 10:09:37 | 显示全部楼层
这么好的教程一定要加分 加精
发表于 2008-9-23 13:42:24 | 显示全部楼层
干的好,伙计:)
发表于 2010-7-13 08:27:36 | 显示全部楼层
:)顶一下
发表于 2010-8-25 15:51:28 | 显示全部楼层
好教程,顶顶顶...
发表于 2011-9-20 10:36:06 | 显示全部楼层
很好的教程!不过为什么logs的文件夹改不过来属性呢?一直是只读?

本版积分规则