处理“返回”的最佳方式?

时间:2012-11-07 14:11:09

标签: php class

我需要一个建议,如何处理具有更多不同回报的函数。
我在班上有这个简单的登录功能:

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 个答案:

答案 0 :(得分: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 :
        ...
}

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

答案 1 :(得分:1)

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

正如Nanne所指出的,你不应该使用流量控制的例外:它们只应表明特殊情况。技术错误显然是一种特殊情况,使用例外情况将是明确和恰当的。

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

开始打破异常的语义,具体取决于此代码与其余代码的匹配方式。例如,能够在其他地方调用登录功能而不必担心抛出不适当的异常可能是有用的或必要的。

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

如果每个失败条件需要明显不同的错误处理机制,那么为每个失败案例返回constant至少可以清楚地说明代码中发生了什么。然后,您可以返回LOGIN_PASSWORDS_DO_NOT_MATCH而不是隐藏号码,然后可以在您的错误代码中进行检查。

答案 2 :(得分:0)

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

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

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

澄清错误代码使用命名常量或name =>代码对的静态数组而不是“魔术数字”

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....
}

答案 3 :(得分:-1)

您可以使用INI文件

将你的错误写入ini文件:

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

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

<?php
$array = parse_ini("er.ini");
echo $array[$log];
?>