CodeIgniter Forums

Full Version: Custom 404 control
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]DieterStruik[/eluser]
Hi CI-ers,

You probably ran across the same problem like me. Trying to avoid the standard 404 page which doesn't include all the CI functionality. Therefore making weird includes, cURL calls etc...

I make use of a language segment in my URI's. Like /en/home. So I needed to route like:

Code:
$route['default_controller'] = 'site';
$route['scaffolding_trigger'] = '';

// When first segment is set proceed normally (language checking done in controller)
$route['(\w{2})/(.+)'] = '$2';

// Catch all (important for 404 and language checking)
$route[':any'] = $route['default_controller'];

You don't need to change any existing functionality. Put this code below in any controller (I usually extend my main controller). It's the native _remap() method which always get called first. Here you can check stuff like a missing method.

Code:
public function _remap($method)
{
    // Check if method exists.
    if (!method_exists($this, $method))
    {
         // Show custom embedded 404 page.
         return;
    }
    // Else call the method with the arguments passed by CI.
    $args = array_slice($this->uri->segment_array(), 3);
    return call_user_func_array(array($this, $method), $args);
}

I hope this will be usefull for some of you. I haven't checked it for different types of errors. Just thought about a missing method call. Please let me know anything better.

El Forum

[eluser]davidbehler[/eluser]
But that only accounts for nonexistent methods. What about nonexistent controllers?

El Forum

[eluser]DieterStruik[/eluser]
Hi, you're right. That still is a problem. I Guess some trick needs to be done first.

El Forum

[eluser]DieterStruik[/eluser]
Hi Waldmeister,

So... first time no success on missing controllers. How about this:

1) Modify the CI error_404.php by replacing the content with:

Code:
<?php
echo file_get_contents('http://'.$_SERVER['SERVER_NAME'].'/nl/site/error404/'.$_SERVER['REQUEST_URI']);
?>

Ofcourse /nl/site/error404 is an existing method of my catch all controller named Site.

2) Add the following code in the catch all controller from my first post.

Code:
public function error404()
{
    // Get all arguments passed.  
    $args = func_get_args();

    // This view shows the $uri string after the /nl/site/error404
    $this->load->view('error404', array(            
        'uri' => join('/', $args)
    ));    
}

El Forum

[eluser]louis w[/eluser]
Why would you have to use curl inside of the built in 404 page?

Another possible solution would be my proposed addition of a _default built in method. At the core level, it's functionality is the same as what you outlined above but it would be a native feature and would not require using _remap to catch everything. For non existant controllers, it would/should call the default controller's _default method.

El Forum

[eluser]DieterStruik[/eluser]
Hmmm... for better understanding it's better to clean things up in clear steps.

STEP 1: routes.php
Code:
$route['default_controller'] = 'firstcontroller';
$route['scaffolding_trigger'] = '';

// When first segment is set proceed normally (language checking done in controller)
$route['(\w{2})/(.+)'] = '$2';

// Catch all (important for 404 and language checking)
$route[':any'] = $route['default_controller'];

STEP 2: The extended controller or method in every controller
Code:
public function error404()
{
    // Get all arguments passed.  
    $args = func_get_args();

    // This view shows the $uri string after the /en/firstcontroller/error404
    $this->load->view('error404', array(            
        'uri' => join('/', $args)
    ));    
}

STEP 3: Replace contents of the error_404.php
Code:
<?php
// Display custom 404 from existing method.
echo file_get_contents('http://'.$_SERVER['SERVER_NAME'].'/en/firstcontroller/error404/'.$_SERVER['REQUEST_URI']);
?>
// Will get page form:
// 'http://www.yoursite.com/en/firstcontroller/error404/wrong/url/segments/like/these'

El Forum

[eluser]louis w[/eluser]
Another possible solution would be to edit the error_404.php error page to load your custom view. I have done this on a view projects.

Code:
<?php header("HTTP/1.1 404 Not Found");

if (function_exists('get_instance')) {
    
    $CI= &get;_instance();
    
    $CI->load->view('errors/404');

} else {

    // Existing html in the error_404.php page

}

El Forum

[eluser]Madmartigan1[/eluser]
@louis: When will get_instance() or the loader class ever be available to the error page?
As far as I know, only config, hooks, and router are loaded at this point.
Please explain how you got this to work.

EDIT: Nevermind :-P

El Forum

[eluser]SitesByJoe[/eluser]
I'm dealing with this right now too. I'm finally ready to move past the default CI 404 page. I'l post my solution shortly. (I hope!)

El Forum

[eluser]SitesByJoe[/eluser]
Louis W's solution did the trick, but I can't seem to get it working quite right yet.