1

我需要一个建议,如何更好地处理具有许多不同回报的功能。
我的课堂上有这个简单的登录功能:

public function login($email, $password){

$record = // Go to database and find what we need.

if($record){
   // Check pass, $user_match = TRUE;
} else {
   return 1;         //No such user. Please register!
}

$active = (1 == $record['is_active']) ? TRUE : FALSE;
$verified = (1 == $record['is_verified']) ? TRUE : FALSE;

//User email and password matched:
if($user_match == true){
   if($verified === true){
       // Start session and insert to db table "online_users"
   // Check that user was inserted to table: $confirm = $stmt->rowCount();

         if($confirm !== 1){
           return 2; //Unexpected technical error. Please try again in a moment.
         }

       return 0;     //0 means that all clear, we good to go.

       } else {
           return 3; //not verified
       }
    } else {
        return 4;    // no match with email and pass, reject!
    }
}

问题是,现在我一直需要检查所有退货,如下所示:

$log = $user->login($_POST['email'], $_POST['pass']);
if($log === 0) {
    //Log in & edirect
} elseif ($log === 1) {
    //No such user. Tell to register
} elseif($log === 2){
    //technical error, try again
} elseif($log === 3){
    //Not verified
} elseif($log === 4){
    //wrong password

现在真的很烦人,想象一下我是否需要检查 20 个退货?有没有更好的办法?如何更高效、更快地做到这一点?
提前致谢。

4

4 回答 4

3

您应该重新考虑此函数的用途并相应地构造返回类型。如果目的是让用户登录,则只能有一个答案:要么有效,要么无效。所以函数的主要返回类型应该是布尔值。如何区分不同的失败原因是一个不同的话题。

选项1:抛出异常:

try {
    if (!$foo->login()) {
        echo 'Invalid credentials';
    }
} catch (UserNotActiveException $e) {
    ...
} catch (UserNotValidatedException $e) {
    ...
}

不一定是最优雅的选择,因为登录失败并不是真正的特殊情况。

选项 2:将错误状态保存在登录提供程序中:

if (!$foo->login()) {
    echo "You're not logged in because ", $foo->loginError();
}

这是否好取决于如何使用该类,否则您可能不希望使其过于有状态。

选项3:将登录问题与用户状态完全分开:

if (!$foo->login($user)) {
    switch ($foo->currentStatus($user)) {
        case $foo::ALL_OK :
             echo 'Login credentials invalid';
             break;
        case $foo::ACCOUNT_INACTIVE :
             ...
    }
}

选项 4:返回一个状态对象:

$result = $foo->login();
switch ($result->status) {
    case $result::ALL_OK :
        ...
}

这基本上就是你现在正在做的事情,只是没有神奇的数字。

于 2012-11-07T14:22:59.873 回答
1

使用异常是提供对错误代码的清晰处理的一种方法,具体取决于它如何适合您的应用程序的其余部分。

正如 Nanne 所指出的,您不应该使用异常来进行流量控制:它们应该只表示异常情况。技术错误显然是一种例外情况,为此使用例外是明确和适当的。

对其余部分使用异常不太清楚,但仍然是一种选择。您可以简单地针对每个失败条件抛出带有不同错误消息的异常,或者针对失败条件具有适当处理程序的不同异常类。

这开始打破异常语义,这取决于这段代码如何与其余代码相适应。例如,能够在其他地方调用登录函数而不必担心它会引发不适当的异常可能是有用或必要的。

最后,可能无法避免需要对每个失败条件进行显式检查并将它们返回到函数中。同样,根据这需要的灵活性,您可以在成功登录时返回 true,或者在失败时返回错误消息(===用于验证结果是否为真,而不仅仅是真实)。或者您可以返回一个带有成功属性和错误条件的对象,这至少使您的错误处理代码成为检查成功和处理错误代码的问题。

如果您需要为每种故障情况提供显着不同的错误处理机制,那么为每种故障情况返回一个常量至少可以清楚地说明代码中发生了什么。然后你可以返回LOGIN_PASSWORDS_DO_NOT_MATCH而不是一个神秘的数字,然后可以在你的错误代码中检查它。

于 2012-11-07T14:13:52.743 回答
0

switch如果您需要许多语句,最好使用if-else语句:

$log = $user->login($_POST['email'], $_POST['pass']);

switch ($log) {
   case 1:
     break; 
   case 2:
     break;
   //etc....
}

为了澄清错误代码,请使用命名常量或名称=>代码对的静态数组,而不是“幻数”

static $ERROR_CODES = array(
   "WRONG_PASSWORD"=>1,
   "WRONG_EMAIL"=>2
);

switch ($log) {
   case LoginClass::$ERROR_CODES["WRONG_PASSWORD"]:
     break; 
   case LoginClass::$ERROR_CODES["WRONG_EMAIL"]:
     break;
   //etc....
}
于 2012-11-07T14:14:45.913 回答
-1

您可以使用 INI 文件

将您的错误写入 ini 文件:

1 = "Error"
2 = " Technical"
3 = "Network"
...

并将其保存到ini文件中。然后使用此代码:

<?php
$array = parse_ini("er.ini");
echo $array[$log];
?>
于 2012-11-07T14:17:31.350 回答