6

这个问题:Best way to return status flag and message from a method in Java与我的类似,但是我会用PHP而不是Java(在这里可能会略有不同)。

问题:

有一种方法可以产生成功的结果(这可能会改变为更成功的结果)或“有问题的”结果。后者意味着操作失败,但知道原因也很重要。想象一个 Authentication 类的方法:

public function login($name, $password)
{
    if (successful_authentication)
    {
        report success
    }
    else
    {
        report failure, explain why (e.g. wrong name/pass, user banned)
    }
}

成功和失败返回true和false是微不足道的,但是如何报告失败的原因呢?

可能的解决方案:

  • 返回true或false并编写另一个方法(getStatus())来获取具体问题:这对我来说感觉有点尴尬
  • 使用例外:因为禁止用户并不是例外(例外是如果用户在打字时死亡,正如本网站上的另一位作者所指出的那样)在这些情况下使用例外是完全错误的(但是如果查询失败,方法可能会引发数据库异常)
  • 成功时返回 true,失败时返回字符串,并带有指示问题的错误代码:使用 PHP,可以通过这种方式获得干净的块,如下所示:

    $loginStatus = $auth->login('name', 'pass');
    if ($loginStatus === true)
    {
        doSomething();
    }
    else
    {
        if ($loginStatus == 'wrong_login_data')
        ...
        elseif ($loginStatus == 'banned')
        ...
        // or with an array full of error messages:
        echo $erroMessages[$loginStatus];
    }
    
  • 返回一个一般的状态(状态)对象:非常优雅的解决方案,也是面向未来的(如果状态的数量变化或稍后应该返回额外的数据没有问题),也许是最好的一个:

    $loginStatus = $auth->login('name', 'pass')
    if ($loginStatus->isSuccess)
    ...
    else
        echo $errorMessages[$loginStatus->errorCode]; // $errorMessages as by the previous example
    
  • 上述两种中的任何一种,但不是纯字符串而是类常量:

    $loginStatus = $auth->login('name', 'pass')
    if ($loginStatus->isSuccess)
    ...
    elseif ($loginStatus->errorCode == Auth::ERR_USER_BANNED)
    ...
    

    这样就没有必要在文档中解释错误代码,并且也会感觉更“自然”(至少对我而言)。

问题:

您会使用什么(上述解决方案或任何其他解决方案)?从长远来看,什么被证明是好方法?

先感谢您!

4

3 回答 3

2

抛出异常。如果需要检查返回值,那么任何不这样做都将允许未经授权的登录。不检查异常会炸毁整个事情,这在这种情况下似乎更可取。

在不太关键的地方,如果我对一个已经存在的对象进行检查,我可能只返回结果代码并有一个单独的函数来检索消息,但我不会特意把一些东西变成一个对象使用该技术。否则,我会使用包含结果代码和消息的状态对象。

于 2010-10-23T17:37:54.593 回答
2

从我记事起,这就是 PEAR 一直在做的事情。所以这是一种久经考验的方法。

class LoginError {
    private $reason;

    public function __construct($reason)
    {
        $this->reason = $reason;
    }

    public function getReason()
    {
        return $this->reason;
    }
}

function isError($response)
{
    return ($response instanceof LoginError);
}

public function login($name, $password)
{
    if (successful_authentication)
    {
        return true;
    }
    else
    {
        return new LoginError('The password is incorrect');
    }
}


$loginStatus = login('name', 'pass');
if (!isError($loginStatus))
{
    doSomething();
}
else
{
    echo $loginStatus->getReason();
}
于 2010-10-23T18:15:56.030 回答
1

我会使用您的“返回一般状态(状态)对象”的变体,其中状态由您的身份验证对象描述。

所以 $auth->login('name', 'pass') 是一个简单的布尔值,而 $auth->getState() 是一个描述状态的枚举或字符串(可能是为最终用户设计的)。

于 2010-10-23T17:44:51.877 回答