检验用户输入信息的正确性几乎是所有 Web 编程者都需要做的事。有句话是永远不要相信你的用户。每一个用户都可能是骇客。
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' />
[% FOREACH type IN c.form.error('username') %]
[% IF type == 'DBIC_UNIQUE' %]
This username is used by another one.
[% END %]
....
[% END %]
这种是比较愚笨的方法。我对这个也没用过几次,所以可能有好办法还没发现。perldoc 中提到了用 yml 来定义错误信息,或者这个比较可行,但是我不太喜欢,因为我在做多语言版本的 Forum
或许我得再仔细研究下错误怎么显示才是最方便的。:) 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 %]