内置的Exception类
<?php
class Exception
{
protected $message = 'Unknown exception'; // 异常信息
private $string; // __toString cache
protected $code = 0; // 用户自定义异常代码
protected $file; // 发生异常的文件名
protected $line; // 发生异常的代码行号
private $trace; // 回溯
private $previous; // 嵌套异常时的上一个异常
public function __construct($message = null, $code = 0, Exception $previous = null);
final private function __clone(); // 私有化克隆,禁止克隆异常类
final public function getMessage(); // 返回异常信息
final public function getCode(); // 返回异常代码
final public function getFile(); // 返回发生异常的文件名
final public function getLine(); // 返回发生异常的代码行号
final public function getTrace(); // backtrace() 数组
final public function getPrevious(); // 之前的 exception
final public function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息
// Overrideable
public function __toString(); // 可输出的字符串
}
?>
如果使用自定义的类来扩展内置异常处理类,并且要重新定义[构造函数]的话,建议同时调用 [parent::__construct()]来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载 [__toString()]并自定义输出的样式。
ps:子类中重写构造方法会覆盖父类的构造方法导致父类的构造方法不能自动执行,所以在子类中的构造方法中手动执行父类的构造方法。
自定义的类来扩展内置异常处理类
<?php
/**
* 自定义一个异常处理类
*/
class MyException extends Exception
{
// 重定义构造器使 message 变为必须被指定的属性
public function __construct($message, $code = 0, Exception $previous = null) {
// 自定义的代码
// 确保所有变量都被正确赋值
parent::__construct($message, $code, $previous);
}
// 自定义字符串输出的样式
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function customFunction() {
echo "A custom function for this type of exception\n";
}
}
自定义异常类后,则可以使用自定义后的异常处理类捕获异常,输出异常信息,接下来看下实际例子
实际例子
1.定义异常代码类
<?php
class ErrorCodes{
const GET_DB_ERROR = 100001;
const QUERY_DB_ERROR = 100002;
const DB_TABLE_ERROR = 100003;
public static $codes = array(
100001 => "Connect DB error",
100002 => "Query DB error",
100003 => "DB or table error",
);
}
2.自定义异常类
<?php
class MyException extends Exception{
private $err_no;
private $err_str;
private $code_obj;
const DEFAULT_ERROR_NO = 100000;
public function __construct($err_no, $code_obj="ErrorCodes") {
if (is_int($err_no) && array_key_exists($err_no, $code_obj::$codes)){
//直接传递异常码时,根据异常码获取自定义异常信息
$errstr = @$code_obj::$codes[$err_no];
}else{
$errstr = $err_no;
$err_no = Glo_Error::DEFAULT_ERROR_NO;
}
if ($errstr == null) {
$errstr = '---Err_no not found . no:' . $err_no;
}
$this->err_no = $err_no;
$this->err_str = $errstr;
$this->code_obj = $code_obj;
//回溯调用类,主要用于打印异常日志,这里省去了打印日志的过程
$stack_trace = $this->getTrace();
$class = @$stack_trace[0]['class'];
$type = @$stack_trace[0]['type'];
$function = @$stack_trace[0]['function'];
$file = @$stack_trace[0]['file'];
$line = @$stack_trace[0]['line'];
if ($class != null) {
$function = "$class$type$function";
}
//执行父类构造方法
parent::__construct($errstr, $err_no);
}
public function getErrNo() {
return $this->err_no;
}
public function getErrStr() {
return $this->err_str;
}
public function getCodeObj(){
return $this->code_obj;
}
}
ps:符号(@)在PHP中用作错误控制操作符。当表达式附加@符号时,将忽略该表达式可能生成的错误消息。如果启用了track_errors功能,则表达式生成的错误消息将保存在变量$php_errormsg中。每个错误都会覆盖此变量。
ps:回溯$this->getTrace()打印的数组结果
array(5) {
[0]=>
array(6) {
["file"]=>
string(35) "/home/www/acpf/lib/Glo/BasePage.php"
["line"]=>
int(95)
["function"]=>
string(7) "process"
["class"]=>
string(25) "Page_Bt_SaveQuestionModel"
["type"]=>
string(2) "->"
["args"]=>
array(0) {
}
}
参考链接:https://www.php.net/manual/zh/language.exceptions.extending.php