1

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

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)){

   }

}
}
4

2 回答 2

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 更改为平面文件(或其他方法),我还需要执行此操作(验证)吗?

如果是这样,代码将进入实体模型(用户)。如果不是,那么代码将进入映射器。我意识到这有点简单,但它通常会让我朝着正确的方向前进。

[编辑]

就我个人而言,如果可能的话,我什至会在表单发布之前进行这一小部分验证。我想在用户发布表单之前让他知道他是否已经拥有该电子邮件的帐户,这样可以节省我们双方的时间和挫败感。最终验证始终可以在用户模型中完成。

祝你好运。

于 2012-12-22T09:59:31.217 回答
1

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

在您的情况下,模型类名称是“用户”;

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

  1. 在模型文件 (User.php) 中包含“模型映射器”文件 (UserMapper.php)
  2. 在 Model 类 (User) 中创建一个名为“isEmailDuplicate($emailAddress)”的公共 STATIC 方法。在这个函数中,创建 Mapper 类 (UserMapper.php) 的对象,并在 Mapper 类对象 (UserMapper.php) 上使用 'Zend_Db_select'( help link ) 执行选择查询。最后将布尔结果返回给调用者。
  3. 从 UserController 调用模型函数。$isEmailDuplicate = 用户::isEmailDuplicate($emailAddress);
于 2012-12-22T08:40:02.097 回答