4

我正在开发一些 API 的 PHP 接口,它可以返回许多(最多一百个)不同的错误代码。当遇到这样的代码时,我的界面应该抛出异常。我的 PHP 有点生疏了,因此我不确定对于当今的 php 程序员来说什么是最合适的选择:

  • 每个错误代码都有一个单独的MyApiThisAndThatError类?
  • 或者有一个通用类MyApiError并提供 API 错误代码作为参数?

我也愿意接受其他建议。

4

3 回答 3

7

TLDR: 使用包含 API 错误代码的通用 MyApiException 类。

Ralph Schindler 在http://ralphschindler.com/2010/09/15/exception-best-practices-in-php-5-3上写了一篇关于一般主题的好文章

如果您阅读全文,您将看到库代码中的最佳实践部分演示(我已针对此上下文修改了他的示例):

// usage of bracket syntax for brevity
namespace MyCompany\Component {

    interface Exception
    {}

    class MyApiException 
        extends \RuntimeException 
        implements Exception
    {}

    class Component
    {
        public static function doSomething()
        {
            $myApiCall->doSomthing();
            if ($myApiCall->hasError) {
                throw new MyApiException($myApiCall->getMessage(), $myApiCall->getErrorCode);
            }
        }
    }
}

假设上面的代码,如果要执行 MyCompany\Component\Component::doSomething(),从 doSomething() 方法发出的异常可以被以下任何类型捕获: PHP 的 Exception、SPL 的 RuntimeException 组件的 MyCompany \Component\MyApiException,或组件的 MyCompany\Component\Exception。这为调用者提供了许多机会来捕获由库中给定组件发出的异常,该异常由返回的 API 错误引发。此外,通过分析构成异常的类型,可以为刚刚发生的异常情况赋予更多的语义意义。

于 2013-03-27T17:47:30.163 回答
3

It depends on few factors. In my opinion these are the reasons for specific exceptions:

  1. You can logically group errors and logically name exceptions.
  2. Errors have additional data that depends on error type (you can store this additional data and users can acces them nicely with set/get).
  3. New error types are added very rarely (but you can always throw some base generic exception for unknown error codes).
  4. Meaning of errors change in time (users of your interface will base on exception type, not underlying error code).
  5. You are ready to properly document your specific exceptions so the users won't have to lookup API documentation based on underlying error code.
于 2013-03-27T14:22:34.407 回答
3

I had a similar issue. When I did it, I divided up all the errors into families (i.e Query, Model, Controller, Form, etc...), then within each error family, I had defined constants for each error code.

Ideally, I wanted to have a unified exception class, but there where certain points where I would have a set of function calls within a try catch block, and it was better to have them divided up into different families so I could do a catch for each error family, that would the appropriately determine what to do next. Yes, I could have had a unified error catcher and a function to determine the family from the error number, but it seemed so less elegant.

于 2013-03-27T13:48:34.053 回答