Welcome Guest, Not a member yet? Register   Sign In
Extending exceptions.. and loading libraries?

I've extended the Exceptions so I could override the show_404 method.

After doing so, I noticed that no Libraries or.. well, anything is loaded. So, I tried the ol' get_instance() and that didn't work. I suppose the exception handler is being called before get_instance exists.

Is there any way I can load a few libraries to handle a 404 page? I'd like to, mostly, load the View library (not the internal one - Coolfactor's Smile )

I've poked around but haven't found much worth following.

[eluser]Colin Williams[/eluser]
Quote:So, I tried the ol’ get_instance() and that didn’t work. I suppose the exception handler is being called before get_instance exists.

"Functions need not be defined before they are referenced, except when a function is conditionally defined."

- http://php.net/functions

I'll dive into it more if my editor stops crashing!

[eluser]Pascal Kriete[/eluser]
It's the same issue that I touched on here.

Some of the 404 exceptions are called before the controller/super-object is instantiated, so you can't get a super-object instance (obviously).

[eluser]Colin Williams[/eluser]
So, looks like you'll need to use load_class(). Also, I had to extend CI_Exceptions and not Exceptions to even get it to work.

class MY_Exceptions extends CI_Exceptions {
  function show_404($page = '')
     $view =& load_class('View');


[eluser]Colin Williams[/eluser]
Quote:Some of the 404 exceptions are called before the controller/super-object is instantiated, so you can’t get a super-object instance (obviously).

Just caught that too. Glad I jumped in on this thread. I've yet to dive into the murky waters of the Exceptions class.

Ahhh. That makes sense then. I've been trying to follow the execution path for codeigniter, but I'm so busy at work today, I keep having to start over.

I'm still going to need to get an instance since the view library calls get_instance().

Is there another way I should approach this? I've never really seen a cover-all post on how to catch 404's and handle them yourself without over-riding the show_404 method - which in and of itself seems limited since it seems to get called before controller/superobject wakes up.

[eluser]Pascal Kriete[/eluser]
I've played with this quite a bit actually (including a rather obscure method using fsockopen that I posted on here somewhere), but in the end it comes down to two realistic options:

1. Eliminate unknown controllers
2. Route everything and have a catchall route

The first one works, because the only 404 called before the super-object 'wakes up' is in the router - the check for a valid controller. The fix is an easy one - override the _validate_request function and change the bottom part:
// ...

            return $segments;

        // Can't find the requested controller...
        show_404($segments[0]);  // remove this

        // Add something like this
        return array('error_controller', 'some_function');

That routes all requests for a non-existent controller to error_controller:Confusedome_function, and from there you can call show_404(). That should take care of most of the 404s you'll ever see (there is a security check in CodeIgniter.php that might cause trouble).

You're still stuck with the old-school 404 error file though.

The second option is a little more tedious, but actually a lot of fun, because it makes urls so much more flexible. And you get a real 404 controller, not just a pseudo-view thing. Example:
$route = array(
                'default_controller'                    => 'main',
                'scaffolding_trigger'                    => '',

                // Session routes
                'login'                                    => 'session/login',
                'logout'                                => 'session/logout',
                'register'                                => 'session/register',
                // User routes
                'home'                                    => 'main/home',
                'terms'                                    => 'main/terms',
                // Utility routes
                'files'                                    => 'utilities/files',
                'preferences'                            => 'utilities/prefs',
                // Project routes
                'project/(:num)'                        => 'project/home/$1',
                'project/create'                        => 'project/create',
                // Catchall 404
                '.*'                                    => 'main/error_404'

All that is assuming you want to maintain the url. Otherwise just toss a redirect header into your 404 template and send them to a real controller.

inparo, thank you.

I didn't even think about using .* in the routes - completely forgot they handled regex. That is actually a perfect solution and is exactly the sort of simplicity I was hoping for.

Thank you, thank you and thank you. As usual, the CodeIgniter community proves itself superior Smile

[eluser]Colin Williams[/eluser]
You still want to show true 404s at some point though... but I guess if you're calling show_404() from your controller, get_instance() should work just peachy.

Is show_404 going to send a 404 header? or should i just fire off a 404 header from the controller if the controller/method doesn't exist?

Theme © iAndrew 2016 - Forum software by © MyBB