php – Lithium和验证复杂的表单输入 – 如何?
我已经做了很多Lithium教程(如果他们帮助别人,下面的链接,以及表明我已完成我的作业:)我了解创建模型,视图,控制器和使用MVC创建的最基本部分基于表单输入的DB记录.
但是,我是MVC for webapps和Lithium的新手,我不确定如何在更复杂的情况下编写代码.这是一个普遍的问题,但我有两个具体的验证问题: >我应该如何验证表单提交的日期数据? 我非常感谢对这些问题的任何帮助,这样的具体例子也将真正帮助我理解如何在其他情况下做好MVC编码! 日期输入 – 验证跨多个表单输入的数据分割 出于UI原因,注册表单要求用户在三个字段中输入他们的DOB: <?=$this->form->field('birthday',array('type' => 'select','list' => array(/*...*/))); ?> <?=$this->form->field('birthmonth','list' => array(/*...*/))); ?> <?=$this->form->field('birthyear','list' => array(/*...*/))); ?> 验证此服务器端的最佳方法是什么?我想我应该利用自动验证,但我不确定对于一组不属于模型的变量的最佳方法.例如.: >我应该在UsersController中对$this-> request->数据进行后期处理吗?例如.在将Users_troller传递给Users :: create之前修改$this-> request->数据. 所有这些似乎都可以工作,虽然有些看起来有点难看,我不知道哪些可能会在未来给我带来重大问题. [编辑:与此密切相关的是将三个表单字段组合到一个字段中以保存在模型中的问题] 电子邮件条目 – 检查两个表单字段是相同的,但只存储一个 对于常识/常规做法,注册表单要求用户指定两次电子邮件地址: <?=$this->form->field('email_address'); ?> <?=$this->form->field('verify_email_address'); ?> 如何编写检查这两个表单字段具有相同值的自动验证规则,但只将email_address保存到数据库中? 这感觉就像上面几乎一样的问题,因为我能想到的可能答案列表是相同的 – 所以我将这个作为一个问题提交,但我非常感谢你对这两个部分的帮助,因为我认为这个解决方案将是微妙的,不同的,同样具有启发性! [编辑:与此密切相关的是不将verify_email_address存储到我的模型和数据库中的问题] 一些关于锂的背景阅读 我已经读过其他人了,但这三个教程让我到了用户所在的位置并立即注册表单… > Blog tutorial 关于密切相关主题的一些其他StackOverflow问题(但没有回答它,也没有回答特定于锂的问题) > this question的一个答案建议创建一个单独的控制器(和模型……?) – 它对我来说感觉不太“锂”,我担心它可能很脆弱/很容易出错 NB:CakePHP风格的答案也很好.我不知道,但它很相似,如果我需要,我相信我可以从中翻译出来!
我建议在模型而不是控制器中执行此操作 – 无论您从何处执行保存,都会发生这种情况.
对于日期字段问题,在模型中,覆盖save()方法并处理将数据中的多个字段转换为一个日期字段,然后再调用parent :: save进行实际保存.任何高级操作都可能发生在那里 您在评论中描述的使用隐藏表单字段来获取错误消息以显示声音的技术非常好. 为了比较两个电子邮件字段是否相等,我建议您定义一个自定义验证器.您可以使用Validator::add在引导程序中执行此操作. use lithiumutilValidator; use InvalidArgumentException; Validator::add('match',function($value,$format = null,array $options = array()) { $options += array( 'against' => '','values' => array() ); extract($options); if (array_key_exists($against,$values)) { return $values[$against] == $value; } return false; }); 然后在你的模型中: public $validates = array( "email" => array( "match","message" => "Please re-type your email address.","against" => "email2" ) ); 编辑:根据评论,这是一种在控制器中进行自定义规则验证的方法: public function save() { $entity = MyModel::create($this->request->data); $rules = array( "email" => array( "match","against" => "email2" ) ); if (!$entity->validates($rules)) { return compact('entity'); } // if your model defines a `$_schema` and sets `$_meta = array('locked' => true)` // then any fields not in the schema will not be saved to the db // here's another way using the `'whitelist'` param $blacklist = array('email2','some','other','fields'); $whitelist = array_keys($entity->data()); $whitelist = array_diff($whitelist,$blacklist); if ($entity->save(null,compact('whitelist'))) { $this->redirect( array("Controller::view","args" => array($entity->_id)),array('exit' => true) ); } return compact('entity'); } 将数据设置为实体的一个优点是,如果存在验证错误,它将自动预填充在您的表单中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |