• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Extending exceptions.. and loading libraries?

#1
[eluser]awpti[/eluser]
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.

#2
[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!

#3
[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).

#4
[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.

Code:
class MY_Exceptions extends CI_Exceptions {
  
  function show_404($page = '')
  {
     $view =& load_class('View');
     $view->method();
     exit;
  }

}

#5
[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.

#6
[eluser]awpti[/eluser]
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.

#7
[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:
Code:
// ...

            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:
Code:
$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.

#8
[eluser]awpti[/eluser]
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

#9
[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.

#10
[eluser]awpti[/eluser]
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?


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2019 MyBB Group.