提问者:小点点

创建一个简单的MVC-不确定验证实现


我正在创建一个简单的 MVC 应用程序来了解有关 MVC 的更多信息。我有一个控制器,它使用UserService类来获取所需的用户:

class UserController extends Controller{
   public function Index(){
      $data['users'] = UserService::getAll();
      $this->view->render($data);
   }

   public function Add(){
      UserService::insert($_POST['username'],$_POST['password']);
   }
}

UserService 类使用 ORM(惯用语)来获取数据:

class UserService{
   public static function getAll(){
      return Model::factory('User')->find_many();
   }

   public static function insert($username,$password){
      $user = Model::factory('User')->create();
      $user->username = $username;
      $user->password = $password; //no good practice in real life offcourse...
      return $user->save();
   }
}

我如何适应这里的一些验证?就像检查值是否为空,密码是否与某个验证模式匹配。。。

我应该做些什么,比如:

//控制器

public function Add(){
   if(UserValidationService::checkPassword($_POST['password'])){
      UserService::insert($_POST['username'],$_POST['password']);
   }else{
      //set some errordata and show the view
   }
}

或者我应该在服务(模型)中进行验证并返回错误?

我对如何正确进行验证有点困惑。

代码更新

class UserController extends Controller{
   public function Add(){
      $result = UserService::insert($_POST['username'],$_POST['password']);
      if($result[0]){
         //result ok, show view
      }else{
         //result not ok, pass errors to view
      }
   }
}

class UserService{
   $errors = "";
   public static function insert($username,$password){
      if(empty($username)){
         $errors .= "Please enter a username.";
      }
      if(empty($password)){
         $errors .= "Please enter a password.";
      }
      if(empty($errors)){
         $user = Model::factory('User')->create();
         $user->username = $username;
         $user->password = $password; //no good practice in real life offcourse...
         $user->save();
         return array(true,$user);
      }else{
         return array(false,$errors);
      }
   }
}

共1个答案

匿名用户

这种约束的验证应该是基于模型的验证。这是因为你不能依赖一个模型被一个控制器使用。

注册用户的模型可能从 5 个不同的页面使用,依赖于 5 个不同的控制器。甚至由第三方。在每个控制器中进行验证将是矫枉过正。您只需要处理模型的返回值。

在您的模式中,您可以

if(empty($param)) {
   return array(false, self::EMPTY_PARAM);
}
if(strlen($param)<self::MINIMUM_LENGTH) {
   return array(false, self::MINIMUM_LENGTH_NOT_REACHED);
}

因此,在控制器中,您正在检查:

   if(!$model_response[0]) {
      return json_encode(array('success' => 0, 'error_msg' => 'Error message, or the constant value from the model, or something else to get proper error message'));
   }

您可以通过仅返回false来简化,我添加的示例是处理不同的错误,因此您可以将正确的字符串/json发送到视图。

/* $model_response here is the return value of the model
 * I did not used associative array returning so
 * if the model return the one I said, the first key (`0`)
 * will be false. So we are checking if the first key is false
 * then testing the second key (`1`) what is its return value
 * in order to handle the error (it's mostly a pseudo code)
 */
if(!$model_response[0]) {
    switch($model_respose[1]):
        case UserModel::EMPTY_PARAM:
            $error_msg = 'Username or password cannot be empty';
        break;
        case UserModel::MINIMUM_LENGTH_NOT_REACHED:
            $errpr_msg = 'Username and password should be at least' . UserModel::MIN_LENGTH . 'characters long';
        break;
     endswitch;
     return json_encode(array('success' => 0, 'error_msg' => $error_msg));
}

因此,您只需通过模型(EMPTY_PARAM、MIN_LENGTH等)设置约束,并由控制器处理它们。您可以决定不处理其中一些。无论如何,模型都会返回 false,但最终用户不会看到正确的消息。

因此,如果第三方使用您的模型,即您有合作伙伴关系,他们有门并使用您的模型为您带来注册,并且他们忘记告诉用户最小长度为 6 个字符,他们仍然无法插入少于 6 个字符的用户名到您的应用程序中,但他们的用户不会明白为什么他们的注册没有完成。