This article introduces the errors and exceptions encountered by PHP programmers. Now I share it with everyone. Friends in need can refer to it
try { // 需要进行异常处理的代码段; throw 语句抛出异常; }catch( Exception $e ) { ... } catch( Exception $e ) { // 处理异常 } contine.....
Not yet The caught exception will report a fatal error: Fatal error:Uncaught exception.....
PHP
will not actively catch exceptions. It needs to actively throw (throw
) exceptions in the program to catch them.
throw
will be automatically thrown upward
throw
The statements after will not be executed
try
must be followed by catch
, otherwise parse error Parse error
try{ $num1=3; $num2=0; if($num2==0){ throw new Exception('0不能当作除数'); echo 'this is a test';//看不到 }else{ $res=$num1/$num2; } }catch(Exception $e){ echo $e->getMessage(); }
Php does not provide many exception classes like
java, so many exceptions will be treated as errors. To change an error into an exception, you need to manually
throwException object
PHP built-in exceptions such as: PDOException,
SplFileObject
Exceptions can be thrown automatically, and the subsequent code can continue to execute.
##1.4 The difference between errors and exceptions
throw will not continue to execute , PHP will try to find a matching
catch
block of code. If the exception is not caught and set_exception_handler()
is not used for corresponding processing, then a serious error (Fatal Error
) will occur and " Uncaught Exception" error message. 1.4.2 Basic syntax structure of exceptions
try - Code that requires exception handling should be placed in
try within a code block to catch potential exceptions. If no exception is triggered, the code continues execution as usual. But if an exception is triggered, an exception will be thrown
throw
- This specifies how to trigger the exception. Each try
or throw must correspond to at least one
catch. Use multiple catch code blocks to catch different kinds of exceptions. catch
- catch
The code block will catch the exception and create an object containing the exception information1.4.3 Rethrow the exception
block. Note that try{}catch{} is required to throw an exception again, and exceptions cannot be thrown directly in the catch code block. Scripts should hide system errors from users. System errors may be important to programmers, but users are not interested in them. To make it easier for users, you can throw the exception again with a user-friendly message.
1.4.4 The difference between errors and exceptions
Error: The error is triggered
throw statement and caught through
catch. If not caught, a fatal error will occur.
overwrite the constructor and toStringtwo functions
, generally Exception
base class At the end, The base class can call the method defined by the custom exception class
/** * 自定义异常类 * Class MyException */ class MyException extends Exception { public function __construct($message = "", $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); } public function __toString() { $message = "<h2>出现异常了,信息如下</h2>"; $message .= "<p>".__CLASS__."[{$this->code}]:{$this->message}</p>"; return $message; } public function test() { echo 'this is a test'; } public function stop() { exit('script end...'); } //自定义其它方法 } try{ echo '出现异常啦'; throw new MyException('测试自定义异常'); }catch (MyException $exception){ echo $exception->getMessage(); echo $exception; } //会继续执行 echo 'continue.........';
try{ throw new MyException('测试自定义异常'); }catch (Exception $exception){ echo $exception->getMessage(); $exception->test(); } catch (MyException $exception){ echo $exception->getMessage(); }
//将错误用错误抑制符吸收,然后抛出异常 If(@!fwrite($filename,$data)) throw new exception(自定义异常) PHP_EOL #换行符
(1) :file_put_contents(LOG_PATH.'error.log';, '错误信息'.' '.date('Y-m-d H:i:s')."\r\n", FILE_APPEND);
(2) :error_log('错误信息'.' '.date('Y-m-d H:i:s')."\r\n",3,LOG_PATH.'error.log');
Exception_Observer.php /** * 给观察者定义规范 * * Interface Exception_Observer */ interface Exception_Observer { public function update(Observable_Exception $e); }
Observable_Exception.php /** * 定义观察者 * Class Observable_Exception */ class Observable_Exception extends Exception { //保存观察者信息 public static $_observers = array(); public static function attach(Exception_Observer $observer) { self::$_observers[] = $observer; } public function __construct($message = "", $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); $this->notify(); } public function notify() { foreach (self::$_observers as $observer) { $observer->update($this); } } }
Logging_Exception_Observer.php /** * 记录错误日志 * Class Logging_Exception_Observer */ class Logging_Exception_Observer implements Exception_Observer { protected $_filename = __DIR__.'/error_observer.log'; public function __construct($filename = null) { if ($filename!==null && is_string($filename)){ $this->_filename = $filename; } } public function update(Observable_Exception $e) { $message = "时间:".date('Y:m:d H:i:s',time()).PHP_EOL; $message.= "信息:".$e->getMessage().PHP_EOL; $message.= "追踪信息:".$e->getTraceAsString().PHP_EOL; $message.= "文件:".$e->getFile().PHP_EOL; $message.= "行号:".$e->getLine().PHP_EOL; error_log($message,3,$this->_filename);//写到日志中 } }
test.php /** *测试 */ header('content-type:text/html;charset=utf-8'); require_once 'Exception_Observer.php'; require_once 'Logging_Exception_Observer.php'; require_once 'Observable_Exception.php'; Observable_Exception::attach(new Logging_Exception_Observer()); class MyException extends Observable_Exception{ public function test() { echo 'this is a test'; } } try{ throw new MyException('出现了异常!'); }catch (MyException $exception){ echo $exception->getMessage(); }
类似set_error_handler
接管系统的错误处理函数,set_exception_handler
接管所有没有被catch
的异常
restore_exception_handler
同restore_error_handler
一样,本质上应该说从异常/错误处理函数栈中弹出一个。比如有一个异常处理函数,弹出一个的话,就没有异常处理函数,如果有异常没有捕获,会交由错误处理函数,如没有错误处理函数,异常最终会有系统错误处理函数处理。如果设置了2个异常处理函数,弹出一个,会交由下面一个异常处理函数处理。
/** * 自定义异常函数处理器 */ header('content-type:text/html;charset=utf-8'); function exceptionHandler_1($e) { echo '自定义异常处理器1<br/>函数名:'.__FUNCTION__.PHP_EOL; echo '异常信息:'.$e->getMessage(); } function exceptionHandler_2($e) { echo '自定义异常处理器2<br/>函数名:'.__FUNCTION__.PHP_EOL; echo '异常信息:'.$e->getMessage(); } set_exception_handler('exceptionHandler_1'); //set_exception_handler('exceptionHandler_2'); //恢复到上一次定义过的异常处理函数,即exceptionHandler_1 //restore_exception_handler(); //致命错误信息 //restore_exception_handler(); throw new Exception('测试自定义异常处理器'); //自定义异常处理器,不会向下继续执行,因为throw之后不会再继续执行;try{} catch{}之后,会继续执行 //回顾:自定义错误处理器会继续执行代码,而手动抛出的错误信息不会继续执行 echo 'test';
/** * 自定义异常类处理器 * Class ExceptionHandler */ class ExceptionHandler { protected $_exception; protected $_logFile = __DIR__.'/exception_handle.log'; public function __construct(Exception $e) { $this->_exception = $e; } public static function handle(Exception $e) { $self = new self($e); $self->log(); echo $self; } public function log() { error_log($this->_exception->getMessage().PHP_EOL,3,$this->_logFile); } /** * 魔术方法__toString() * 快速获取对象的字符串信息的便捷方式,直接输出对象引用时自动调用的方法。 * @return string */ public function __toString() { $message = <<<EOF <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>出现异常了啊啊啊啊</h1> </body> </html> EOF; return $message; } } set_exception_handler(array('ExceptionHandler','handle')); /** * try catch不会被自定义异常处理!!!! */ try{ throw new Exception('this is a test'); }catch (Exception $exception) { echo $exception->getMessage(); } throw new Exception('测试自定义的异常处理器');
异常:
自定义异常处理器不会向下继续执行,因为throw
之后不会再继续执行try{} catch{}
之后,会继续执行错误:
自定义错误处理器会继续执行代码,而手动抛出的错误信息不会继续执行
/** * 方式一:ErrorException错误异常类 * @param $errno * @param $errstr * @param $errfile * @param $errline * @throws ErrorException */ function exception_error_handler($errno,$errstr,$errfile,$errline){ throw new ErrorException($errstr,0,$errno,$errfile,$errline); } set_error_handler('exception_error_handler'); try{ echo gettype(); }catch (Exception $exception){ echo $exception->getMessage(); }
/** * 方式二:自定义异常类 * Class ErrorToException */ //显示所有的错误 error_reporting(-1); class ErrorToException extends Exception{ public static function handle($errno,$errstr) { throw new self($errstr,0); } } set_error_handler(array('ErrorToException','handle')); set_error_handler(array('ErrorToException','handle'),E_USER_WARNING|E_WARNING); try{ echo $test;//notice,不会被处理 echo gettype();//warning //手动触发错误 trigger_error('test',E_USER_WARNING); }catch (Exception $exception){ echo $exception->getMessage(); }
header('Content-type:text/html;charset=utf-8'); class ExceptionRedirectHandler{ protected $_exception; protected $_logFile = __DIR__.'redirect.log'; public $redirect='404.html'; public function __construct(Exception $e){ $this->_exception=$e; } public static function handle(Exception $e){ $self=new self($e); $self->log(); // ob_end_clean()清除所有的输出缓冲,最后没有缓存的时候会产生通知级别的错误 while(@ob_end_clean()); header('HTTP/1.1 307 Temporary Redirect'); //临时重定向 header('Cache-Control:no-cache,must-revalidate');//no-cache强制向源服务器再次验证,must-revalidate可缓存但必须再向源服务器进行确认 header('Expires: Sat, 28 Mar 2016 13:28:48 GMT'); //资源失效的时间 header('Location:'.$self->redirect); //跳转 } public function log(){ error_log($this->_exception->getMessage().PHP_EOL,3,$this->_logFile); } } set_exception_handler(array('ExceptionRedirectHandler','handle')); $link=@mysqli_connect('127.0.0.1','root','1234561'); if(!$link){ throw new Exception('数据库连接出错啦'); }
完!
参考课程视频:那些年你遇到的错误与异常
相关推荐:
The above is the detailed content of Errors and exceptions encountered by PHP programmers Part 2: Exceptions. For more information, please follow other related articles on the PHP Chinese website!