Catalyst and FormValidator::Simple
检验用户输入信息的正确性几乎是所有 Web 编程者都需要做的事。有句话是永远不要相信你的用户。每一个用户都可能是骇客。
Catalyst 中我最喜欢的检测插件是 Catalyst::Plugin::FormValidator::Simple
我可以用个简单一点的例子来说明一下。
假设最简单的用户注册。一个用户名 6-12 个字符。密码 6-20 个,输入两次,两次都一样。 email 一个。要求大致正确。用户名和 email 必须与数据库里已有的不冲突。
Controller 大致为这样子:
上面的是检查,然后如果出错要把错误显示出来。这里我觉得有点不方便。比如说 username 到底是违反了哪一条。 $c->form->error('username') 返回的是一个匿名数组,如 [ 'DBIC_UNIQUE', 'LENGTH' ] 我的习惯是将错误消息显示在 username text 输入框的旁边,而不是把所有的错误消息都放一起。这样判断起来很麻烦。我差不多得这么写:
或许我得再仔细研究下错误怎么显示才是最方便的。:) later~
update
我发现这样子是可行的:
Catalyst 中我最喜欢的检测插件是 Catalyst::Plugin::FormValidator::Simple
我可以用个简单一点的例子来说明一下。
假设最简单的用户注册。一个用户名 6-12 个字符。密码 6-20 个,输入两次,两次都一样。 email 一个。要求大致正确。用户名和 email 必须与数据库里已有的不冲突。
Controller 大致为这样子:
sub register : Global {
my ( $self, $c ) = @_;
$c->stash->{template} = 'user/register.html';
return unless ($c->req->param('process'));
# execute validation.
$c->form(
username => [[ 'DBIC_UNIQUE', $c->model('DBIC')->resultset('User'), 'username' ], qw/NOT_BLANK ASCII/, [qw/LENGTH 6 20/] ],
password => [qw/NOT_BLANK/, [qw/LENGTH 6 12/] ],
email => [qw/NOT_BLANK EMAIL_LOOSE/, [qw/LENGTH 5 20/], [ 'DBIC_UNIQUE', $c->model('DBIC')->resultset('User'), 'email' ] ],
{ passwords => ['password', 'confirm_password'] } => ['DUPLICATION'],
);
my $result = $c->form;
return if ( $result->has_error );$c->form 就是 Catalyst::Plugin::FormValidator::Simple 所提供的函数。DBIC_UNIQUE 检验机制是由 FormValidator::Simple::Plugin::DBIC::Unique 所提供的。主要用于检测表中的某一字段是否是 unique 独一的。我们所看到的如 NOT_BLANK LENGTH EMAIL_LOOSE DUPLICATION 都是 FormValidator::Simple 所自带的检测机制。还有 DATE 用于检测输入的日期是否合法,Regex 等。可以查阅 perldoc FormValidator::Simple上面的是检查,然后如果出错要把错误显示出来。这里我觉得有点不方便。比如说 username 到底是违反了哪一条。 $c->form->error('username') 返回的是一个匿名数组,如 [ 'DBIC_UNIQUE', 'LENGTH' ] 我的习惯是将错误消息显示在 username text 输入框的旁边,而不是把所有的错误消息都放一起。这样判断起来很麻烦。我差不多得这么写:
<input type='text' name='username' length='12' />这种是比较愚笨的方法。我对这个也没用过几次,所以可能有好办法还没发现。perldoc 中提到了用 yml 来定义错误信息,或者这个比较可行,但是我不太喜欢,因为我在做多语言版本的 Forum
[% FOREACH type IN c.form.error('username') %]
[% IF type == 'DBIC_UNIQUE' %]
This username is used by another one.
[% END %]
....
[% END %]
或许我得再仔细研究下错误怎么显示才是最方便的。:) later~
update
我发现这样子是可行的:
[% IF c.form.error('username') %]
[% IF IF c.form.error('username', 'DBIC_UNIQUE') %]
This username is used by another one.
[% ELSE %]
username should be 6-20 chars.
[% END %]
[% END %]
3 Comments:
FYI..
Data::FormValidator 可以把出错信息在 DFV 的 profile 里定义出来,然后错误信息就缺省显示在出错的框边了。不知道 C::P::F::S 里是否有这个功能。
我通常把错误信息放到一个 conf 文件里,然后在 DFV 的 profile 里把检查的部分通过 $dfv->set_current_constraint_name('html_tag_found');
付一个值,然后在 DFV 里的 msgs
msgs => { ... constraints => { 'html_tag_found' => $self->config_param('form_err.html_tag_found'),
},}
DFV 很好用。
最近在用 CGI::Application. 感觉很简练,干净。Catalyst 一直没看了。
Qiang
I'll try it later. both Data::FormValidator and C:A
thanks. :)
qiang,
dfv里这点不方便:
msgs是针对constraint的,不同的field
如果用了同一种内置的constraint,那他们的出错信息就不得不是一样的了
Post a Comment
Links to this post:
Create a Link
<< Home