如果避免其他条件,如何避免PHP嵌套,并编写干净,易于理解的代码?

时间:2019-12-09 09:50:28

标签: php codeigniter authentication coding-style

我正在codeigniter中编写一个登录方法,用户将在其中输入电子邮件和密码,然后它将执行以下操作:

  1. 验证用户输入->如果有效,请执行第2点
  2. 从数据库获取用户详细信息->如果成功查询,请执行第3点
  3. 验证密码->如果验证通过,请登录系统

我知道我可以通过使用纯嵌套if ... else条件来实现上述目的,但是那样将非常繁琐且难以阅读。 所以,我以这种方式尝试过-

// Empty array to hold processing errors
$processing_errors = array();

// Check for valid input
if(!$is_valid_input) array_push($processing_errors, "Invalid inputs");

// Get user details
if($get_user_details)
{   
    // Verify the user
    if(!$is_correct_user) array_push($processing_errors, "Incorrect username or password.");
}
else array_push($processing_errors, "Database query error");

// Check if processing errors is empty 
if(empty($processing_errors)) echo "Successfully logged in."; // Success
else foreach($processing_errors as $errors) echo $errors; // Errors

但是上述方法的问题在于,即使返回Check for valid input之后,它仍将执行代码,即使它返回false也会花费不必要的处理时间。

编写简洁,清晰的可读代码的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以将这些方法分解为仅公开登录请求方法的方法,并将其他所有内容保持内部(如private方法所示),如下所示。 userLogin是请求的来源。

代码段:

class LoginController extends CI_Controller{
    private $errors;

    function __construct(){
        $this->errors = []; // initialize error bag to an empty array
        /*
          load needed models
        */
    }

    private function validateInput($post_data){
        /*
          validate user details
        */

        if(!$is_valid_input){
            $this->errors[] = '';
        }

        return $is_valid_input;
    }

    private function getUserDetails($post_data){
        /*
            get the user data using models
        */
        return $user_data;
    }

    private function verifyUser($post_data){
        $user_data = $this->getUserDetails($post_data);
        $is_correct_user = $user->email == $post_data['email'] && password_verify($post_data['password'],$user->password);

        if(!$is_correct_user){
            $this->errors[] = 'Incorrect username or password.';
        }

        return $is_correct_user;
    }

    private function displayErrors(){
        foreach($this->errors as $current_error){
            echo $current_error,"<br/>";
        }
    }

    public function userLogin(){
        $data = $this->input->post();
        try{
            if($this->validateInput($data) && $this->verifyUser($data)){
                echo "Successfully logged in";
                /* Your futher code */
            }else{
                $this->displayErrors();
            }
        }catch(Exception $e){
            echo $e->getMessage(); // if you throw some Exception in your model for some situations. Better to have exact class name of Exception for faster lookup of the class
        }       
    }
}