使用Form类进行表单字段验证 (phpsa系列教程之二)

来源:互联网 发布:伯克利加州大学 知乎 编辑:程序博客网 时间:2024/05/16 19:32
使用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 
=== $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 &copy; 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表单验证就讲到这里了, 学习与使用过程中有任何问题,欢迎发邮件与我共同讨论.