PHP通过异常处理空值处理

时间:2014-10-05 16:05:11

标签: php exception nullpointerexception

当我尝试访问null对象上的成员或方法时,有没有办法告诉PHP抛出异常?

E.g:

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

现在,我只收到以下错误,这些错误无法处理:

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 ...

我想要抛出一个特定的异常。这可能吗?

5 个答案:

答案 0 :(得分:2)

您可以使用set_error_handler()将警告变为异常,因此当发生警告时,它会生成一个异常,您可以在try-catch块中捕获它。

致命错误无法转化为异常,它们是专为php设计的,以便尽快停止。但是我们可以通过使用register_shutdown_function()

进行最后一分钟处理来优雅地处理胎儿错误
<?php

//Gracefully handle fatal errors
register_shutdown_function(function(){
    $error = error_get_last();
    if( $error !== NULL) {
        echo 'Fatel 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";
}

答案 1 :(得分:1)

将此代码添加到之前包含或执行的文件中:

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

答案 2 :(得分:1)

尝试使用此代码来捕获所有错误:

<?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);
    }
);

它应该在其他代码之前执行或包含。

如果你不介意的话,你也可以实现一个Singleton来避免全局变量,或让它抛出两个例外。

答案 3 :(得分:1)

从PHP7开始,您可以捕获致命错误,如下所示:

$x = null;
try {
    $x->method();
} catch (\Throwable $e) {
    throw new \Exception('$x is null');
}

答案 4 :(得分:0)

正确答案应该是:否。在任何PHP版本中都是不可能的。