php - 在 php 中扩展异常的逻辑问题
问题描述
对于 PHP,我使用以下类结构来处理异常:
class ProjectException extends Exception {
... logical code for handling exceptions, functions that are relevant to every exception my project throws go here
}
class SpecificException extends ProjectException {
protected $codePrefix = 'SE';
const ERROR_SOMETHING_BAD_HAPPENED = 100;
const ERROR_SOMETHING_SIMMILARLY_BAD_HAPPENED = 101;
/* no functions go in this class, this class is only to specify the code prefix of the exception, and the error codes used by it */
}
如果我想捕获异常,我通常使用以下类型的异常捕获:
try {
/** try something here **/
} catch (SpecificException $e) {
switch ($e->getCode()) {
case SpecificException::ERROR_SOMETHING_BAD_HAPPENED:
/** react to the exception based on it's code, and try to recover **/
default:
/** react to every unexpected code, which may appear if the tried function is modified,
and throws a new exception code of the same type, and stop the execution of the
script, storing the error in the database **/
}
}
我的问题如下。我想“锁定”一些文件不被编辑,例如一些异常文件。我为什么要这样做,是因为我正在尝试使我的部分代码可移植,以便它可以用于我们正在处理的其他项目中。
我的想法是,稍后在新项目中,如果出现新的东西,并且应该制作新的异常代码,我将扩展“锁定”异常,并将新的错误代码编写为const
扩展类中的 a。可能发生的现实生活场景是Account
课堂。可移植代码中已经设计了一个裸Account
类,具有登录和注册功能,但是在每个不同的项目中,这些帐户将获得项目特定的新功能。因此,在新项目中,我将扩展可移植项目Account
类,并在那里编写相关功能。
从理论上讲,这是可行的,但我意识到,我认为以后管理这将是一个真正的痛苦,因为:
- 捕获异常时,我现在要么需要捕获父异常,以捕获每个抛出的异常,要么我必须编写两个(三个、四个等)单独的 catch 块,具体取决于我扩展原始父异常的次数
- 如果我捕捉到父异常,我不能只抛出所有代码,而不知道代码的来源(父类或子类)
基本上我将不得不为这些编写类似的 try catch 块:
try {
/** some code to try **/
} catch (SpecificException $e) {
/** this will catch everything that is SpecificException or SpecificExtendedException or SpecificDoubleExtendedException **/
switch ($e->getCode()) {
case SpecificException::ERROR_IN_SPECIFIC:
/** do something **/
break;
case SpecificException::ERROR_TWO_IN_SPECIC:
/** do something **/
break;
case SpecificDoubleExtendedException::ERROR_IN_SECOND_EXTENDED_EXCEPTION:
/** do something **/
break;
default:
/** as it was originally written **/
break;
}
}
有人对我应该如何进行有任何想法吗?“锁定”一些可移植文件并将新的异常代码添加到这些“锁定”文件中定义的异常中最自然的方法是什么?
解决方案
您可以简单地在您的ProjectException
类中添加这样的方法:
public function getCodeFor(string $name): int
{
return (int)constant("static::ERROR_$name");
}
这使用constant
辅助函数和static
关键字来检索在调用该方法的对象的实际类中定义的常量。
然后你可以有你的try
块,这将适用于任何类扩展SpecificException
:
switch ($e->getCode()) {
case $e->getCodeFor('SOMETHING_BAD_HAPPENED'):
/** do something **/
break;
case $e->getCodeFor('SOMETHING_SIMILARLY_BAD_HAPPENED'):
/** do something **/
break;
case $e->getCodeFor('SOMETHING_SPECIFICALLY_BAD_HAPPENED'):
/** do something **/
break;
}
注意:显然,使用字符串会使您失去 IDE 重构常量的能力。但是由于您无法提前知道哪些类将定义给定代码(或者您可以,但不希望必须这样做),所以这是一个合理的解决方法。
注意 2:可能有更好的方法来做设计方面的事情(正如@Barmar 指出的那样,询问软件工程可能更适合于架构讨论)。这个答案只是试图为您当前的问题提供编程解决方案,而不改变所述设计。
推荐阅读
- gcc - 制作依赖关系:使用 gcc 跳过供应商和包头?
- php - 获取帖子作者图片 - Wordpress
- java - 如果不是以管理员身份运行,cmd 无法识别 Java 命令
- summary - BlueSKy 摘要数值统计分析
- javascript - 使用矩js计算数组中所有对象的所有持续时间的总和
- android - 如何在 ScrollView 上显示滚动条?
- bash - 链码参数错误:JSON 输入意外结束
- c# - 我如何处理 C# 中的 Ping 异常
- github - GraphQL | 我们可以使用指令在 GitHub GraphQL API 中通过编程语言实现搜索吗?
- python - Flask SQLAlchemy 数据库会话提交模式