<?php // 报告所有错误(适用于开发环境) ini_set('display_errors', 'On'); error_reporting(-1); /** * 自定义异常(继承通用异常Exception) */ class MyException extends Exception { /** * 构造方法 * * @param string $message 异常信息 * @param int $code 异常代码 * @param Throwable|null $previous */ public function __construct(string $message = '', int $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); // 调用父类通用异常Exception的构造方法 } } /** * Demo类 */ class Demo { /** * 测试方法(参数只允许传入bool数据类型,其余数据类型均抛出异常) * * @param mixed $var 任意参数(重要提醒:形参数据类型必须为mixed,不能为bool,否则会发生隐式转换导致永远不会抛出异常) * @return bool 若$var为bool数据类型则原样返回,否则抛出异常 * @throws MyException 自定义异常 */ public function func(mixed $var): bool { if (is_bool($var)) { return $var; } ob_start(); var_dump($var); $dump = trim(ob_get_clean()); // 设置异常的message和code $message = "参数无效(仅支持bool类型),您输入的是:$dump"; $code = 1024; // code可自定义 throw new MyException($message, $code); // 抛出异常后不会再执行后面的代码 // echo 'Unreachable statement'; // 这里不会执行,因为上面抛出了异常 } } $demo = new Demo(); try { $demo->func(true); echo 'try-1 ===> 无异常' . PHP_EOL; // try-1 ===> 无异常 } catch (MyException $e) { echo 'catch-1 ===> ' . $e->getMessage() . PHP_EOL; } try { $demo->func(9527); echo 'try-2 ===> 无异常' . PHP_EOL; } catch (MyException $e) { echo 'catch-2 ===> ' . $e->getMessage() . PHP_EOL; // catch-2 ===> 参数无效(仅支持bool类型),您输入的是:int(9527) } try { $demo->func(false); echo 'try-3 ===> 无异常' . PHP_EOL; // try-3 ===> 无异常 } catch (MyException $e) { echo 'catch-3 ===> ' . $e->getMessage() . PHP_EOL; } //========== 总结 ==========// // 1、函数或方法如果可能会抛出异常,那么调用处必须使用try-catch捕获异常,因为如果不捕获异常而程序又恰好出现异常,那么系统就会报致命错 // 误“Fatal error: Uncaught MyException”。 // 2、PHP有很多标准异常和预定义异常,在创建自定义异常前可先查阅PHP官方文档,看是否有满足需求的标准异常或预定义异常,优先使用这些异常, // 在不能满足需求的情况下才创建自定义异常。 // 其实PHP的标准异常和预定义异常已经覆盖了日常大部分错误,如数据类型错误可以使用TypeError,数据类型正确但值错误可以使用ValueError, // 甚至除数为零时的错误DivisionByZeroError都为我们准备好了。 // 在大多数情况下,开发者都不需要创建自定义异常,只要使用new关键字创建标准异常或预定义异常的对象,并设置对象的$message属性为开发者 // 想展示的错误信息,然后通过throw关键字将异常对象抛出去即可。 // PHP官方文档地址:https://www.php.net/manual/zh/spl.exceptions.php // 3、Exception是通用异常,抛出该异常在维护和调试时帮助比较小,所以在实际开发中应该尽量使用标准异常、预定义异常、自定义异常。 // 4、写try-catch捕获异常时,try{}里面应该只写非稳定代码(即可能会抛出异常的代码),稳定代码不要写在try{}里面,最佳实践方案是每个try{} // 里面有且只有一行会抛出异常的代码。 // 5、一段代码在执行过程中如果有多处地方可能会抛出异常,不要嵌套try{},也不要把所有非稳定代码都写在一个try{}里面,而是逐个单独处理, // 这样在出现异常时能够更灵活地应对(如return或exit),代码也更容易维护。 // 6、try{}里面的函数或方法抛出异常后,函数或方法后面的代码就不会再执行了,而是转去执行异常对应的catch{},所以如果需要接收函数或方法 // 的返回值就要特别注意,如:$var = $demo->func(9527),由于func(9527)抛出了异常,后续代码都不会再执行了,所以$var变量并没有被定义, // 后续使用$var会报Undefined variable的Warning,最安全的办法是在try{}前面先初始化$var变量。 // PHP标准库(SPL)提供的标准异常 // -------------------------------------------------- // class BadFunctionCallException extends LogicException // class BadMethodCallException extends BadFunctionCallException // class DomainException extends LogicException // class InvalidArgumentException extends LogicException // class LengthException extends LogicException // class LogicException extends Exception // class OutOfBoundsException extends RuntimeException // class OutOfRangeException extends LogicException // class OverflowException extends RuntimeException // class RangeException extends RuntimeException // class RuntimeException extends Exception // class UnderflowException extends RuntimeException // class UnexpectedValueException extends RuntimeException // 预定义异常 // -------------------------------------------------- // class Exception implements Throwable // class ErrorException extends Exception // class Error implements Throwable // class ArgumentCountError extends TypeError // class ArithmeticError extends Error // class AssertionError extends Error // class DivisionByZeroError extends ArithmeticError // class CompileError extends Error // class ParseError extends CompileError // class TypeError extends Error // class ValueError extends Error // class UnhandledMatchError extends Error // final class FiberError extends Error
Copyright © 2024 码农人生. All Rights Reserved