我已经创建了一个简单的ExceptionHandler类:
class ExceptionHandler{
public function __construct(){
set_exception_handler(array($this, 'handleException'));
}
public function handleException(\Exception $exception){
echo $exception->getMessage() . $exception->getLine() . $exception->getFile());
}
}
ExceptionHandler
对象在处理过程中的最早可能时刻创建。在ExceptionHandler
之后不久,将构建一个使用数据库存储数据的Session组件。当使用APC时,会话组件设置以下内容以正确关闭会话:
register_shutdown_function('session_write_close');
我之前执行了一个测试,关闭了MySQL服务器,运行了应用程序。令人困惑的是,异常被 ExceptionHandler
捕获,但同时仍未被捕获并由 xdebug 输出:
SQLSTATE[HY000] [2002] ????,??????????? at line 133 in RedBean_Driver_PDO.php. //This is generated by my exception handler
//These were uncaught and processed by Xdebug
Fatal error: Uncaught exception 'Exception' with message 'PDO::__construct() [133
( ! ) Exception: PDO::__construct() [pdo.--construct]: [2002] ????,??????????? (trying to connect via tcp://localhost:3306) in RedBean_Driver_PDO.php on line 133
Call Stack
//Call stack
这可能是什么原因导致的?我的理解是,
ExceptionHandler
应该能够捕获除在ExceptionHandler
内抛出的异常之外的所有未捕获异常。
更新:
我有一种感觉,这与在关闭时调用的session_write_close
有关。session_write_close需要访问数据库,但数据库不可用。然后会抛出异常。由于脚本执行已结束,ExceptionHandler
不可用,因此我们得到了一个未捕获的异常。有没有什么办法解决这个问题?我正在运行在Windows 7机器上使用mod_cgi的Apache 2.2上的fcgi PHP 5.3.9。
堆栈跟踪:
# Time Memory Function
1 2.0323 767336 ExceptionHandler->handleException( ) //Initial exception caught + handled
2 2.0334 773968 Session->write( ) //Script shutdown started (session_write_close to database)
3 2.0335 774344 Database->findOne( )
4 2.0335 774640 Database->__call( )
5 2.0335 774728 call_user_func_array( )
6 2.0335 775016 RedBean_Facade::findOne( )
7 2.0335 775016 RedBean_Facade::find( )
8 2.0335 775384 RedBean_OODB->find( )
9 2.0335 775384 RedBean_QueryWriter_AQueryWriter->selectRecord( )
10 2.0335 775448 RedBean_QueryWriter_AQueryWriter->safeTable( )
11 2.0335 775536 RedBean_QueryWriter_AQueryWriter->check( )
12 2.0335 775536 RedBean_Adapter_DBAdapter->escape( )
13 2.0335 775536 RedBean_Driver_PDO->Escape( )
14 2.0335 775536 RedBean_Driver_PDO->connect( )
15 2.0336 776200 PDO->__construct( ) //Cannot connect to database
16 4.0433 782768 ErrorHandler->handleError( ) //Error converted to exception
我有一种感觉,这似乎无法真正避免,在生产环境中display_errors
将被关闭。然而,我对此解决方案并不完全满意,因为它似乎不是非常“干净”。
$exception-> getFile());
,使其变为$exception->getFile());
。 - user895378