在Zend 1.11中,我是否在Model或DB Model Mapper中进行了验证检查?

时间:2012-12-22 07:48:01

标签: model-view-controller zend-framework

在下面我有一个模型和一个模型映射器的情况下,我有点困惑,我应该把验证函数放在哪里,例如考虑以下内容:

models
-> User
-> UserMapper

Class User{

  private $id;
  private $name;
  private $email;

  }

Class UserMapper extends Zend_Db_Table_Abstract{

  function findById($id){
  }

  function save(User $user){
  }

}

我需要设置它以便新用户对象不能与现有用户对象具有相同的电子邮件 - 我将在哪里放置验证逻辑来​​检查它,即在模型或模型映射器中?它会是:

Class UserController{

  function doAction(){
    $user = new User();
    $u = new UserMapper();
    ...
    // is this the right way to do this?
    if($user->validate()){

    }

    // or is this the right way to do this?

   if($u->validate($user)){

   }

}
}

2 个答案:

答案 0 :(得分:2)

您经常会在注册表单中看到此验证,您可以使用注册表单对象进行验证,也可以使用User对象。

无论哪种方式Zend_Validate::DbNoRecordExistsZend_Validate::DbRecordExists都可能有用,可以用作表单验证器:

//form demo
class Reg_Form extends Zend_Form
{  
public function init() {
   $name = new Zend_Form_Element_Text('name');
        $name->setLabel('Name');
        $name->setAttrib('placeholder', 'Username');
        $name->setOptions(array('size' => 20));
        $name->addFilter('StringToLower');
        //truncated for brevity
        $name->addValidator(new Zend_Validate_Db_NoRecordExists(array(
                    'table' => 'users',
                    'field' => 'name'
                )));
        $this->addElement($name);
    }
}

或模型中的独立验证器。

//Entity Model demo, This is used to check against MP3 database
/**
 * Does record already exist in DB
 *
 * Pass in the mapper to use as a string.
 * Will trigger predefined validator DbNoRecordExists
 *
 * @param string $mapper accepted values are: 'album' 'artist' 'track'
 * @return boolean returns true if no record exists
 */
protected function dbNoExist($mapper)
{
    switch ($mapper) {
        case 'album':
            $value = $this->taginfo->getAlbum();
            $options = array(
                'table'  => 'album',
                'field'  => 'title'
            );
            break;
        case 'artist':
            $value = $this->taginfo->getArtist();
            $options = array(
                'table'  => 'artist',
                'field'  => 'name'
            );
            break;
        case 'track':
            $value = $this->taginfo->getMd5();
            $options = array(
                'table' => 'track',
                'field' => 'hash'
            );
    }
    $validator = new Zend_Validate_Db_NoRecordExists($options);
    if ($validator->isValid($value)) {
        //no record exists
        return TRUE;
    } else {
        //record exists
        return FALSE;
    }
}

我试图在我的项目中回答这些问题的方式是:

如果我将数据持久性从MySql更改为平面文件(或其他方法),我是否还需要执行此操作(验证)?

如果是,则代码进入实体模型(User)。如果没有,则代码将进入映射器。我意识到这有点过分了,但它通常会让我走向正确的方向。

<强> [编辑]

就个人而言,如果可能的话,我会在表格发布之前做一点点验证。我希望让用户知道他在发布表单之前是否已经拥有该电子邮件的帐户,这样可以节省我们的时间和挫败感。最终验证总是可以在用户模型中完成。

祝你好运。

答案 1 :(得分:1)

与数据库表相关的任何复杂逻辑或验证都应该转到“模型”类(用户)。不要将它们放在Table类(UserMapper)中。

在您的情况下,模型类名称为“User”;

我按照以下方法进行重复的电子邮件检查。

  1. 在模型文件(User.php)中包含'Model Mapper'文件(UserMapper.php)
  2. 在Model类(User)中创建名为'isEmailDuplicate($ emailAddress)'的公共STATIC方法。在这个函数中,创建Mapper类的对象(UserMapper.php)并使用'Zend_Db_select'(help link)对Mapper类对象(UserMapper.php)执行select查询。最后将布尔结果返回给调用者。
  3. 从UserController调用Model函数。 $ isEmailDuplicate = User :: isEmailDuplicate($ emailAddress);