I have been working with CodeIgniter for quite a while now and I'm currently doing a project for a client that would like a custom 404 page. Everything is fine and the 404_override
it works great.
My issue comes when a visitor is trying to access a article that do not exist I would like to call the show_404()
function, but this shows me the "out of box"
404 page and not the one written in the 404_override.
I have seen some fixes for older versions, but I can't get it to work in 2.1. So if anyone can help me out of this I would be really grateful.
Redirect is cleanest; loading a view could work too.
The problem here is that show_404() is usually called AFTER your controller has already loaded (something had to tell it show the 404 after all). CI doesn't like loading a second controller at that point, which is the primary hurdle.
Your best option probably is extending the show_404() function in the Exceptions class to redirect to your 404 route. Without a redirect, you'll be stuck with showing a view or something that you know has all the "extra data" it needs prior to calling the 404 (or I guess you could load it in the Exceptions class too). It can get really complicated in some dynamic views.
You obviously want something more advanced than just editing the 404 template in the errors folder. I've had problems trying to access get_instance() from that file, as sometimes it's loaded before the controller is constructed. So, be careful if you try that ;)
Update: Here's a working example of extending the show_404() function to load a view
<?php
// application/core/MY_Exceptions.php
class MY_Exceptions extends CI_Exceptions {
public function show_404()
{
$CI =& get_instance();
$CI->load->view('my_notfound_view');
echo $CI->output->get_output();
exit;
}
}
My fast approach to solving the problem is to create a function in an autoloaded helper file in the project i'm working on. This helper just redirects to the custom 404 page. So i just call show_my_404()
instead of show_404()
function show_my_404(){
//Using 'location' not work well on some windows systems
redirect('controller/page404', 'location');
}
function show_404($page = '', $log_error = TRUE)
{
if ($log_error)
{
log_message('error', '404 Page Not Found --> '.$page);
}
redirect(base_url().index_page().'/controller/error_page');
//OR
//redirect('SOME URL');
exit;
}
I was searching for the same thing, but found quite long solutions like creating own error controller and exception class or simply redirecting to 404 page (which isn't good semantically).
So I did bit research on how CI calls '404_override' route internally. Here's the solution I came up with:
// Override show_404 method
function show_404(){
// Load Router and Core classes.
$RTR =& load_class('Router', 'core');
// Get class and method for 404 from routes.php
$x = explode('/', $RTR->routes['404_override']);
$class = $x[0];
$method = (isset($x[1]) ? $x[1] : 'index');
// Get current class and method for callback
$callback_class = $RTR->fetch_class();
$callback_method = $RTR->fetch_method();
// Can also log here, using callback class and method.
// Create object for callback
$CI = new $callback_class;
call_user_func_array(array(&$CI, $method), array_slice(array($class,$method), 2));
} // End!
Add this function in system/core/CodeIgniter.php file.
This will override show_404 function. You can call it from your controllers and it will call '404_override' route given in routes.php file.