当前位置: 首页 > 后端技术 > PHP

php7异常与错误处理与自定义异常

时间:2023-03-29 17:40:29 PHP

首先声明,笔者PHP7.2版本异常与错误概述什么是异常?异常是指程序运行过程中不符合预期,与正常流程不同的情况。比如你连接数据库,发现在参数都写完的情况下连接失败了,这就不是预期的结果了。try-catch可以捕获的错误是什么?是属于php程序本身的问题,一般是语法不规范和环境问题导致编译器无法通过检查甚至无法运行。平时遇到的warming和notices都是error,只是级别不同而已。例如:TypeError(类型错误)我指定的函数参数类型与传入参数不一致ArithmeticError(算术错误)ParseError(分析错误)在加载的文件中,包含“demo.php”或eval();ParsingfailedduetosyntaxerrorAssertionError(assertionerror)assert生效时产生这个错误DivisionByZeroError(denominatoriszero)在除法等操作中,分母为0除了这几种情况,其余都是异常异常处理以前的php5.X无法被try-catch捕获。在php7.x中,定义了一个Throwable接口,大部分Error和Exception都实现了这个接口。我们可以在try-catch中抛出这个错误,所以我们想以后如果要捕获异常,而不知道这个异常是Error还是Exception,可以抛出try{...}catch(Throwable$e){...}php中的错误级别也是Parseerror>FatalError>Waning>Notice>DeprecatedDeprecated最低级别的错误(notrecommended,notrecommended)出现在使用一些过期函数的时候,并且程序继续执行NoticeNotice级别的错误usesomeundefinedvariables,constantsorarraykeyswithoutaddingQuotes会出现,程序继续执行E_NOTICE//Runtimenotification。指示脚本遇到可能表现为错误的情况。E_USER_NOTICE//用户产生的通知信息。Waning警告级别的错误程序有问题,需要修改代码!!!程序继续执行E_WARNING//运行时警告(非致命错误)。E_CORE_WARNING//PHP初始化和启动期间发生的警告(非致命错误)。E_COMPILE_WARNING//编译警告E_USER_WARNING//用户生成的警告信息FatalErrorWrongprogramwithwronglevel直接报错,需要修改代码!!!要中断程序的执行,可以使用register_shutdown_function()函数在程序终止前触发一个函数。E_ERROR//致命的运行错误,错误无法恢复,暂停脚本的执行E_CORE_ERROR//PHP启动时初始化过程中的致命错误E_COMPILE_ERROR//编译时的致命错误,像一个E_ERRORE_USER_ERROR//生成自定义错误信息通过Zend脚本引擎。例如使用PHP函数trigger_error(错误类型设置为:E_USER_ERROR)ParseerrorSyntaxparsingerrorSyntaxcheckstageerror,需要修改代码!!!中断程序的执行,除了修改ini文件,将错误信息写入日志外,并不能完全满足我们的需求,大多数时候,我们需要手动重写异常处理。PHP为我们提供了三个函数来帮助我们处理它们。它们是承载错误处理器的set_error_handler()函数,我们可以自定义错误处理流程。如果这个函数之前的代码出现错误,我们自定义的处理函数将不会被调用,因为设置这个函数后error_reporting()就会失效。以下级别的错误不能被用户自定义函数处理:E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING这个函数只能捕获我们的一些Warning和Note级别的错误set_exception_handler()用于未捕获的异常处理register_shutdown_function()function:注册一个在php终止时执行的函数,用于捕获PHPErrors:FatalError、ParseError等。该方法是PHP脚本执行结束前最后调用的函数,如脚本错误、die()、退出、异常和正常结束。如果用于错误处理,需要和error_get_last()一起使用,获取最后发生的错误。//例如:register_shutdown_function('shutdown');functionshutdown(){if($error=error_get_last()){var_dump($error);}}$name//不写;No.执行结果Parseerror:syntaxerror,unexpected';'/app/swoole/errorDemo.php中第34行Emmmmm这不是废话吗?明明不执行?其实原因是在程序执行之前,我们的php会先检查我们程序的语法。如果没有问题,我们就可以执行我们的程序了。我们上面的代码没有通过我们的语法检查,所以直接报错了。那么问题来了?当我们在框架中时,为什么框架会向我们报错?框架的错误处理在框架中,它的代码是通过一个入口文件加载的。当我们检测php中的语法错误时,我们只会检查我们的index.php是否有错误,并不会检测到require文件中的代码。在Index.php文件中通常会定义一些错误异常处理。当我们的代码出错时,是运行时检测到的错误,我们的框架可以根据我们写的错误异常自行处理。下面我们给出ThinkPHP5.2异常处理的例子//[应用入口文件]index.phpnamespacethink;//加载基础文件require__DIR__。'/../thinkphp/base.php';//支持优先使用静态方法设置Request对象和Config对象//执行应用并响应Container::get('app')->run()->发送();在我们的入口文件中,base.php被加载到这个文件中,TP定义了自己的异常处理//加载Loader类需要__DIR__。'/library/think/Loader.php';//注册自动加载Loader::register();//注册错误和异常处理机制Error::register();//实现日志接口if(interface_exists('Psr\Log\LoggerInterface')){//doSomething}//注册类库别名Loader::addClassAlias([//doSomething]);/***注册异常处理*@accesspublic*@returnvoid*/publicstaticfunctionregister(){错误报告(E_ALL);set_error_handler([__CLASS__,'appError']);set_exception_handler([__CLASS__,'appException']);register_shutdown_function([__CLASS__,'appShutdown']);可以看到TP在入口脚本中注册了异常处理机制,分别注册了Error、Exception、Shutdown的处理。后续所有的异常都不会沿用PHP原有的异常,而是TP自定义的异常。该参考资料讨论的是php错误和异常处理。