Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a decent error 404 handler for CodeIgniter?

CodeIgniter has /system/application/errors/error_404.php which is displayed when there is a 404 due to what is effectively a "controller not found" condition. However, for my project, I really need this error to be handled just like it is when a method is missing from the controller class. In that case, I show a normal view with a pretty "Page not found: Perhaps you meant this?..." page complete with database-generated navigation etc.

My thoughts are that I could do one of two things:

  1. Create a header("Location: /path/to/error_page") call to redirect to an existing (or special) controller's 404 handler
  2. Add some kind of default router to handle it.

What is the best way to achieve the required result? Are there any pitfalls to watch out for?

like image 476
Mark Hatton Avatar asked Nov 06 '22 21:11

Mark Hatton


1 Answers

I use CodeIgniter with Smarty. I have an additional function in my Smarty class called notfound(). Calling notfound() sets the correct header location to a 404 page and then displays a 404 template. The template has an overrideable title and message so it's very versatile. Here's some sample code:

Smarty.class.php

function not_found() {
header('HTTP/1.1 404 Not Found');

if (!$this->get_template_vars('page_title')) {
    $this->assign('page_title', 'Page not found');
    }

    $this->display('not-found.tpl');
    exit;
}

In a controller I can do something like this:

$this->load->model('article_model');
$article = $this->article_model->get_latest();

if ($article) {
    $this->smarty->assign('article', $article);
    $this->smarty->view('article');
} else {
    $this->smarty->assign('title', Article not found');
    $this->smarty->not_found();
}

Likewise, I can change the code in /system/application/error/error_404.php to:

$CI =& get_instance();
$CI->cismarty->not_found();

It works great, uses a small amount of code, and doesn't duplicate 404 functionality for different types of missing entities.

I think you could do a similar thing with the built-in CodeIgniter views. The important thing is to spit out the header before you do your view stuff.

Update: I use a custom Smarty wrapper similar to the one described here:

Using Smarty with CodeIgniter

like image 167
GloryFish Avatar answered Nov 12 '22 13:11

GloryFish