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

Php 创建简单的MVC-不确定验证实现,php,validation,model-view-controller,Php,Validation,Model View Controller,我正在创建一个简单的MVC应用程序来了解更多关于MVC的信息。 我有一个控制器,它使用UserService类来获取所需的用户: class UserController extends Controller{ public function Index(){ $data['users'] = UserService::getAll(); $this->view->render($data); } public function Add()

我正在创建一个简单的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(idiorm)获取数据:

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);
      }
   }
}

此类约束的验证应该是基于模型的验证。这是因为您不能依赖于单个控制器将使用单个模型

您的注册用户模型可以从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);
}
您可以通过只返回false来简化,我添加的示例是处理不同的错误,因此您可以向视图发送适当的string/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,但最终用户将看不到正确的消息


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

好的,但是如果我想返回多个错误呢?如果我想在成功保存时返回一个用户对象(使用已生成的userID),该怎么办?根据您的反馈,我在底部更新了新代码,这是一个好做法吗?@randomizer我发现您的代码中有几个问题。首先,与PHP中的Java/C不同,您没有这种显式类型绑定<代码>字符串$var=''无效。然而,如果一个strying是空的,我不会依赖它继续工作。一旦达到约束,停止使用
return
执行方法。真正的错误消息应该从控制器生成。你可以告诉控制器一个提示,它可能是什么样子的
const EMPTY\u USER='EMPTY\u USER'
,然后如果控制器看到你正在返回
self::EMPTY\u USER
,告诉用户
请输入用户名。
如果你真的需要创建的对象,返回对象也很好:)这是你的方式。在您成功尝试的情况下,
$model\u response[1]
将是用户object@randomizer如果您怀疑模型为什么不应该返回最终用户错误消息,那是因为您违反了单一责任原则。例如,您的合作伙伴可能希望返回不同的错误,如果他想要操作,他需要检查
if($model_response[1]=='Please enter a username')/* $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));
}