Question

I have an exception in application/core named prefix_Exceptions.php with the same class name. I try to throw this exception from a controller and I get:

Fatal error: Class 'prefix_Exceptions' not found in user_controller.php

In application/core/prefix_Exceptions.php:

<?php
class prefix_Exceptions extends CI_Exceptions {
    public function __construct() {
        parent::__construct();
    }

    public function test() {
        echo "This is a test.";
    }
}

And in application/controllers/user_controller.php:

<?php
class User_Controller extends CI_Controller {
    public function view($id = '0') {
        $this->load->model('user_model');
        $u = $this->user_model->getUser($id);

        if (!isset($u)) {
            $this->exceptions->test(); // ???
        }
        echo "Test: $u";
    }
}

Oh, and my prefix is set to prefix_:

$config['subclass_prefix'] = 'prefix_';

I've read about a dozen threads on this issue and none of them fix my exception so that it can be thrown by the controller.

Was it helpful?

Solution

The main reason your code is not working, is (as the error message suggests): your prefix_invalid_user.php is never loaded. CI does not know to load this file, as you are not following the required file naming scheme.

If you want to extend a built-in class, you have to use the same class name, except you change the prefix from CI_ to MY_ (or whatever prefix you set in your config).

To extend the class CI_Exceptions you would have to name it MY_Exceptions and save that php file in /application/core/MY_Exceptions.php. Then, and only then, will CI auto-load it for you.

However you should also know that CI's exceptions class isn't actually for throwing exceptions (the name is misleading, but CI_Exceptions handles error reporting). As you can see in the /system/core/Exceptions.php file, the CI_Exceptions class does not extend PHP's native Exceptions class, which is necessary to create custom, throwable exceptions.

If you want custom, throwable exceptions you have to create your own wrapper for them, and load/autoload it as a library.

Edit:

As per the OP's request, I'm adding the other half of the solution, which was to simply fetch the class object from CI's innards. For this, we can use the load_class function, which will return our class object if it has been instantiated, and if not, it will instantiate and return it.

$foo = load_class('Exceptions', 'core', $this->config->item('subclass_prefix'))

Then we can access the methods of our custom Exceptions class as so:

$foo->someMethodName();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top