21 May 2006
This post may be outdated due to it was written on 2006. The links may be broken. The code may be not working anymore. Leave comments if needed.
检验用户输入信息的正确性几乎是所有 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 %]


blog comments powered by Disqus