7

Is there a way I can tell PHP to throw an exception when I am trying to access a member or method on a null object?

E.g.:

$x = null;
$x->foo = 5; // Null field access
$x->bar(); // Null method call

Right now, I only get the following errors which are not nice to handle:

PHP Notice:  Trying to get property of non-object in ...
PHP Warning:  Creating default object from empty value in ...
PHP Fatal error:  Call to undefined method stdClass::bar() in ...

I would like to have a specific exception being thrown instead. Is this possible?

1
  • Register a global error handler and throw your own exceptions. Commented Oct 5, 2014 at 16:16

5 Answers 5

6

Since PHP7 you can catch fatal errors, example below:

$x = null;
try {
    $x->method();
} catch (\Throwable $e) {
    throw new \Exception('$x is null');
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can turn your warnings into exceptions using set_error_handler() so whenever an warning occurs, it will generate an Exception which you can catch in a try-catch block.

Fatal errors can't be turned into Exceptions, they are designed for PHP to stop asap. However, we can handle the fatal error gracefully by doing some last-minute processing using register_shutdown_function()

<?php

//Gracefully handle fatal errors
register_shutdown_function(function(){
    $error = error_get_last();
    if( $error !== NULL) {
        echo 'Fatal Error';
    }
});

//Turn errors into exceptions
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try{
    $x = null;
    $x->foo = 5; // Null field access
    $x->bar(); // Null method call
}catch(Exception $ex){
    echo "Caught exception";
}

Comments

1

Add this code in the file that is included or executed before anything else:

set_error_handler(
    function($errno, $errstr, $errfile, $errline) {
        throw new \ErrorException($errstr, $errno, 1, $errfile, $errline);
    }
);

Comments

1

Try this code to catch all errors:

<?php    
$_caughtError = false;

register_shutdown_function(
        // handle fatal errors
        function() {
            global $_caughtError;
            $error = error_get_last();
            if( !$_caughtError && $error ) {
                throw new \ErrorException($error['message'],
                                          $error['type'],
                                          2,
                                          $error['file'],
                                          $error['line']);
            }
        }
);

set_error_handler(
    function($errno, $errstr, $errfile, $errline) {
        global $_caughtError;
        $_caughtError = true;
        throw new \ErrorException($errstr, $errno, 1, $errfile, $errline);
    }
);

It should be executed or included before other code.

You can also implement a Singleton to avoid global variables or let it throw two exceptions, if you don't mind.

Comments

0

The correct answer should be: NO. This is not possible in any PHP version.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.