如果可用,使用特殊类,如果不是,则使用基类

时间:2016-12-28 16:59:11

标签: php

我是use来自基础框架的代码中的一个类。但它可能还没有出现:

use BaseFramework\Libs\SpecialException;

所以这个use - Statement会导致错误。即对于框架,我想这样做不能使用SpecialException:

use Exception as SpecialException;

这样我就不需要更改代码了。

我了解到use只是为完整的命名类创建别名。

我想使用原始的SpecialException,如果这是不可能的,我想使用Exception。 我想知道,PHP的最佳实践或推荐方法是什么来解决这个问题?

4 个答案:

答案 0 :(得分:1)

您可以决定使用class_exists投掷哪一个,但实际使用它会非常讨厌。

示例:

try {
   // do something
} catch (\Exception $e) {
    // you'd still need to catch a common exception to all your custom types
    if (class_exists('SomeCustomException')) {
        throw new SomeCustomException; // or whatever
    }
}

但是你需要做到这一点或者其他地方同样糟糕的事情。

你的问题表明这里的实际答案是实现你自己的自定义异常,然后抛出它,因为你可以完全控制它。

有时框架通过共享互操作性包来解决这类问题,因此它们可以符合通用接口,抛出相同的异常等等。

答案 1 :(得分:0)

由于SpecialException可能包含Exception不包含的方法,变量和内容,因此没有坚如磐石的方法来实现您的需求。只需用更通用的类替换类,一旦使用一些更专用的方法,可能会导致麻烦。

你可以看到这个帖子用于处理类别名来实现你想要的行为,但由于上面提到的原因,我不推荐它: Why use class alisases?

您应该使用factory-Pattern,只需导入最终自定义类的超类型并使用该超类型。

很快,因为你需要在一个实例上调用一个方法,你不确定该方法是否存在(由于向上转换) - 你的类定义(或者至少是所需的方法)被放入继承树中的错误级别。

答案 2 :(得分:0)

为什么不延长Exception?像这样......

namespace ProjectName\Exceptions\SpecialException;

class SpecialException extends Exception
{
    // Implement custom properties and methods if required. Optional.
}

此处我们有一个使用SpecialException的自定义类:

use \ProjectName\Exceptions\SpecialException;

class DocumentRepository
{
    public static function fetchByID($docID)
    {
        throw new SpecialException("Document does not exist");
    }
}

现在您无需担心SpecialException是否存在。如果调用代码抛出常规Exception,它将被捕获,但如果它抛出SpecialException,它仍然会被捕获,因为新的异常基类是Exception

try
{
    $doc = DocumentRepository::fetchByID(12);
}
catch(Exception $e)
{
    die($e->getMessage());
}

或者,如果你想抓住你可以做的SpecialException(我强烈推荐这个):

try
{
    $doc = DocumentRepository::fetchByID(12);
}
catch(SpecialException $e)
{
    die($e->getMessage());
}

更新以回答评论中的问题

作为使用框架的开发人员,您有一个存放自定义类,文件等的位置对吗?我假设这个位置是ProjectName/lib。并且假设您使用的框架位于目录ProjectName/BaseFramework

您的自定义SpecialException将位于ProjectName/lib/Exceptions/SpecialException.php

目前,该框架不包含此例外。因此,在您要使用SpecialException的文件中,您可以使用以下use行:

use \ProjectName\Exceptions\SpecialException

当框架最终实现此SpecialException时,您只需将use行替换为此行:

use \BaseProject\Exceptions\SpecialException

就这么简单。

如果您尝试以其他用户建议的方式执行此操作,则系统中将包含死代码。最终实施SpecialException时,对要使用的Exception类型的检查将是多余的。

这假设您使用的是像composer或其他处理自动加载的东西。

答案 3 :(得分:0)

好的,感谢@dognose和@bcmcfc提供的一些线索,这对我有用:

 use BaseFramework\Libs\SpecialException;
 if (!class_exists("SpecialException")) {
     class_alias("Exception", "SpecialException");
 }