0

I'm using Phil Sturgeon's REST_Controller in CodeIgniter, but I would like to use try...catch blocks in a way more familiar to an old Java programmer like myself. So, I added a function to Phil's controller:

    function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext){
        $ee = new ErrorException($errstr, 0, $errno, $errfile, $errline, $previous);
        throw $ee;
    }

Then in the __construct method of the controller, I tried to connect that function up with error handling:

    set_error_handler("exception_error_handler");

When I now run a controller that extends REST_Controller, I get this error message:

set_error_handler() expects the argument (exception_error_handler) to be a valid callback

If I put the function and the call set_error_handler in the sub-class, there is no error and my try...catch blocks catch the exception whenever there is an error. Why isn't my callback valid in the super class?

DavidHyogo
  • 2,838
  • 4
  • 31
  • 48

2 Answers2

3

Your child class is inheriting your parent's constructor.

set_error_handler(array($this, 'exception_error_handler'));

EDIT

After setting:

function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext){
        $ee = new ErrorException($errstr, 0, $errno, $errfile, $errline, $previous);
        throw $ee;
    }

TO:

protected static function exception_error_handler($errno, $errstr, $errfile, $errline, $errcontext){
        $ee = new ErrorException($errstr, 0, $errno, $errfile, $errline, $previous);
        throw $ee;
    }

You should be able to call it as follows:

__construct(){
set_error_handler(function(){self::exception_error_handler("exception_error_han‌​dler")});
}
Zander Rootman
  • 2,178
  • 2
  • 17
  • 29
  • When I put that line in the parent's constructor, it just causes a 500 Internal Server Error. Do you mean I should put that in the child constructor? What I want is to set this up in one place and then all child classes have access to the same functionality. – DavidHyogo Mar 05 '14 at 14:44
  • Hmmm. Curiouser and curiouser. When I put that line in the child's constructor, everything works. I've read the incredibly confusing PHP docs. How did you work that out from them? I still want to be able to set the error handler more globally in the parent, though. – DavidHyogo Mar 05 '14 at 14:49
  • hmmm, try:" set_error_handler(function(){self::customErrorHandler();}); " - And put it in the parent consturctor – Zander Rootman Mar 05 '14 at 14:54
  • Sorry also wanted to add, you should make the "customErrorHandler()" function static on the parent's side. – Zander Rootman Mar 05 '14 at 14:55
  • Sorry, copied some old code over without editing. Here's what I wanted to post. Try: "set_error_handler(function(){self::exception_error_handler("exception_error_handler")});" – Zander Rootman Mar 05 '14 at 15:03
  • No sorry. I tried various combinations of your suggestion but they all cause a 500 internal server error. It's past midnight here so got to go for now. Thanks for the help. Up 1 for pointing in what feels like the right direction. – DavidHyogo Mar 05 '14 at 15:14
  • I'm afraid {self::exception_error_handler("exception_error_han‌​dler")}); displays an error in Netbeans and see previous comment. – DavidHyogo Mar 05 '14 at 15:17
  • It's strange that you should get an 500 error from the server without any PHP Output. Check if you have error reporting turned on: http://www.php.net/function.error_reporting. Also, are you sure "ErrorException" receives the correct arguments from "exception_error_handler" – Zander Rootman Mar 05 '14 at 15:26
1

I'm grateful to user3345621 for pointing me in the right direction. I scrolled down the PHP manual entry for set_error_handler to the comments and found a great piece of advice about 3 ways of setting a callback function.

In REST_Controller, I added the exception_error_handler function as mentioned in my original question, except that I made it static as recommended by user 3345621.

protected static function exception_error_handler($errno, 
                                                  $errstr, 
                                                  $errfile, 
                                                  $errline, 
                                                  $errcontext){
        $ee = new ErrorException($errstr, 0, $errno, $errfile, $errline, $previous);
        throw $ee;
    }

I then noticed the early_checks method in the REST_Controller. I added the following call to set_error_handler in the early_checks method:

set_error_handler(array(&$this, 'exception_error_handler'));

The comment in the PHP manual says that ampersand is important.

Now when an error occurs in a sub-class, an ErrorException is thrown as I require.

DavidHyogo
  • 2,838
  • 4
  • 31
  • 48