为什么PDOException不能被set_error_handler、set_exception_handler所捕获
入口文件注册错误处理机制
// 设定报错级别为全部
error_reporting(E_ALL);
// 设定错误日志记录文件
ini_set('error_log',SYSTEM_LOGS_DIR.date("Ymd") . '_log.txt');
// 显示错误日志
ini_set('display_errors', '1');
// set_error_handler — 设置用户自定义的错误处理函数
set_error_handler([__CLASS__, 'appError']);
// set_exception_handler — 设置用户自定义的异常处理函数
set_exception_handler([__CLASS__, 'appException']);
// register_shutdown_function — 注册一个会在php中止时执行的函数,脚本执行完成或者 exit() 后被调用
register_shutdown_function([__CLASS__, 'appShutdown']);
但是当pdo insert的时候,如果我的字段过长
出现data too long for column的时候这两个函数都没有捕获到
只能通过到
try{
$WorkListModelObj->insert($historyWork);
}catch(\Throwable $e){
// PDOException
echo $e->getCode();
echo $e->getMessage();
}
所捕获到,这是为啥,有时候数组 undefined index 的时候:
PHP Notice: Undefined index: test -- 无法被try-catch捕获-会被set_error_handler所捕获
有时候
// a();// PHP Fatal error: Uncaught Error: Call to undefined function a() -- try-catch也不能捕获
// php由上到下解析的,如果前面已经注册了set_exception_handler,那么将会被捕获,注意必须是这一行前面,不能是后面
我凌乱了
如何才能实现一个完美捕获所有php错误和异常并进行自己处理的程序
附上:
<?php
/**
*
* 错误处理机制
* @author wystanxu <435861851@qq.com>
* @since 1.0.0
*
*/
class ErrorCatch
{
/**
* 注册异常处理
* @access public
* @return void
*/
public static function register()
{
// 设定报错级别为全部
error_reporting(E_ALL);
// 设定错误日志记录文件
ini_set('error_log', dirname(__DIR__) . '/' . date("Ymd") . '_log.txt');
// 显示错误日志
ini_set('display_errors', '1');
// set_error_handler — 设置用户自定义的错误处理函数
set_error_handler([__CLASS__, 'appError']);
// set_exception_handler — 设置用户自定义的异常处理函数
set_exception_handler([__CLASS__, 'appException']);
// register_shutdown_function — 注册一个会在php中止时执行的函数,脚本执行完成或者 exit() 后被调用
register_shutdown_function([__CLASS__, 'appShutdown']);
}
/**
* 错误处理
* @access public
* @param integer $errno 错误编号
* @param integer $errstr 详细错误信息
* @param string $errfile 出错的文件
* @param integer $errline 出错行号
* @param array $errcontext 出错上下文
* @return void
* @throws ErrorException
*/
public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])
{
echo "appErr";
$msg = '错误编号:' . $errno . "\n\r";
$msg .= '错误信息:' . $errstr . "\n\r";
$msg .= '文件:' . $errfile . "\n\r";
$msg .= '在第:' . $errline . "行\n\r";
echo $msg;
// 记录错误日志到文本
error_log($msg, 3, ini_get("error_log"));
}
/**
* 异常处理
* @access public
* @param Exception $e 异常对象
* @return void
*/
public static function appException($exception)
{
$msg = "捕获异常: ".$exception->getMessage()."\n\r";
echo $msg;
// 记录错误日志到文本
error_log($msg, 3, ini_get("error_log"));
}
/**
* 异常中止处理
* @access public
* @return void
*/
public static function appShutdown()
{
// 只有错误导致的程序终止才会托管至错误处理函数
if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
echo "appShutdown".PHP_EOL;
self::appException(new ErrorException(
$error['type'],
$error['message'],
$error['file'],
$error['line']
));
}
}
/**
* 确定错误类型是否致命
* @access protected
* @param int $type 错误类型
* @return bool
*/
protected static function isFatal($type)
{
return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);
}
}
// 注册自定义错误处理
ErrorCatch::register();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
错误和异常级别不一样,有的错误和异常会直接终止脚本。
在 index.php 中引入另一个文件 controller.php , 在 index.php 捕获 controller.php 异常和错误,执行 index.php 。
这样的话就算 controller.php 抛出严重的错误和异常,导致 controller.php 脚本终止,但并不影响 index.php ,在 index.php 中可以正常捕获到异常。
这样自己写脚本注册错误处理能正常捕获到,但是在phalcon框架之中是不能捕获到
Emm.. 运行后输出:
`
捕获异常: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (usin
g password: NO)
`