前面我们介绍了如何用ThinkPHP创建一个Hello,PHP!应用,下面我们就来完成一个表单的提交和处理。
这个示例项目,我们需要和数据库打交道,因此会涉及到Vo类和Dao类的定义。
另外,项目入口文件里面多了一行:
- // 加载数据库配置文件
- require('./config.php');
用户加载数据库配置文件,请修改该配置文件里面的参数满足你的测试环境。
假设我们以用户注册表单为例,项目名称为Form,用户的数据表结构如下:
- CREATE TABLE `think_user` (
- `
id` int(11) unsigned NOT NULL auto_increment,
- `
name` varchar(30) NOT NULL default '',
- `
nickname` varchar(50) NOT NULL default '',
- `
password` varchar(32) NOT NULL default '',
- `
email` varchar(255) NOT NULL default '',
- `
registerTime` int(11) unsigned NOT NULL default '0',
- `
status` tinyint(1) unsigned NOT NULL default '0',
-
PRIMARY KEY (`id`)
- ) ;
在提供的下载文件里面,包含了form.sql文件,请把该文件导入到config.php文件指定的数据库(注意:ThinkPHP默认的数据表主键名采用id,如果采用其他名称作为主键名,需要在初始化Dao对象的时候使用参数)
根据这个表结构,我们把用户表转换成Vo对象定义如下:
- class UserVo extends Vo
{//类定义开始
-
var $id; // 用户编号
-
var $name; // 用户账户
-
var $nickname; // 用户昵称
-
var $password; //登录密码
-
var $registerTime; //注册时间
-
var $status; // 用户状态
-
var $email; // 用户邮箱
}//类定义结束
并保存成UserVo.class.php文件放到项目目录下面的Lib\Vo目录下面。
接下来,我们需要定义一个UserDao类,来进行数据访问和存取。
这个项目我们只是简单的保存表单提交的数据,没有特别的数据访问操作,因此不需要定义任何Dao方法,直接构造一个Dao类的子类就行了,类定义如下:
- class UserDao extends Dao
{//类定义开始
-
}//类定义结束
并保存为UserDao.class.php 放到Lib\Dao目录下面。
接下来就是定义我们需要进行的操作,对于这个表单应用,我们有两个操作,一个是数据录入操作,我们定义为add操作,另外一个是表单保存操作,我们定义为insert操作(注意:操作的名称可以随意定义,但是尽量有含义并且不能是PHP的关键字,例如定义一个new操作就是不允许的,呵呵~)
但是,由于ThinkPHP框架内置的Action基础类已经定义了通用的add和insert操作,所以我们在Action类里面可以不需要再自己定义操作。我们依然采用Index模块来执行这个表单应用,因此IndexAction类的定义如下:
- class IndexAction extends Action
{
-
- }
//end class
由于User数据表里面有两个数据不是由表单提交过来的,需要系统来生成或者采用默认值,所以我们需要给insert操作定义一个专门的处理方法,来及时对表单数据进行处理。
ThinkPHP框架有两种方式来完成表单数据的预处理操作,一种是采用定义
_operation方法来完成,该方法是在表单提交(包括修改表单)后系统会自动寻找是否存在_operation方法,如果存在就会首先调用,下面的例子就是我们在该预处理方法里面定义了用户的注册时间和默认状态,保证数据存储的时候有相应的数据。
- function _operation(){
-
$_POST['registerTime'] = time();
-
$_POST['status'] = 1;
- }
第二种方法,是借用ThinkPHP框架的前置操作功能,因为ThinkPHP在执行某个操作之前会首先寻找是否存在_before_(前置操作),我们通过这个功能来进行表单数据的预处理也是一样的道理。
- function _before_insert(){
-
$_POST['registerTime'] = time();
-
$_POST['status'] = 1;
- }
两种方式虽然不同,但是道理一样,但是,对于上面两种方法,对Action类和Dao类的命名必须是和Vo类一致才可以完成自动操作。但是,我们当前使用的是默认的Index模块,所以,需要使用另外的方法,就是我们重载系统的insert操作,因为ThinkPHP框架自带的insert操作出于通用性考虑,考虑地比较全面,包括表单的文件上传功能全部内置了。如果我们不需要这么复杂,完全可以重载一个简单的insert操作方法,下面我们来看下如何定义一个数据对象的保存操作。
- function insert(){
-
// 用快捷方式创建UserDao对象
-
$dao = D("User");
-
// 根据表单提交创建UserVo对象
-
$user = $dao->createVo();
-
// 在这里添加更多的表单数据验证操作
- // .............
- //
- // 添加表单提交没有的数据
-
$user->registerTime = time();
-
$user->status = 1;
-
// 保存UserVo对象到数据库
-
$result = $dao->add($user);
- if (
$result){
-
$this->success('用户注册成功!');
- }else {
-
$this->error('用户注册失败!');
- }
- }
在表单数据提交后通常都会有一个验证的过程,这个暂时不列在本篇的范围之内,关于数据验证和校验我们另外描述。
最后的工作就是定义模版了,由于该应用只有add一个可视化操作,所以,我们只需要定义一个add模版就可以了。
模版内容如下:
- <FORM METHOD=POST ACTION="__URL__/insert">
- <
TABLE>
- <
TR>
- <
TD align="right">用户名:TD>
- <
TD><INPUT TYPE="text" NAME="name">TD>
TR>
- <
TR>
- <
TD align="right">密码:TD>
- <
TD><INPUT TYPE="password" name="password">TD>
TR>
- <
TR>
- <
TD align="right">昵称:TD>
- <
TD><INPUT TYPE="text" NAME="nickname">TD>
TR>
- <
TR>
- <
TD align="right">邮箱:TD>
- <
TD><INPUT TYPE="text" NAME="email">TD>
TR>
- <
TR>
- <
TD align="right">TD>
- <
TD><INPUT TYPE="submit" value="注册">TD>
TR>
TABLE>
FORM>
模版里面用了一个特别__URL__,这个字符属于框架特殊字符,在编译模版的时候会自动替换,可以省去你写action地址的不便,表示当前模块URL地址 ,__URL__/insert 就表示提交表单到当前模块的insert操作方法。
为了给出保存成功的提示,我们还需要一个提示页面,ThinkPHP采用一种跳转提示方法,你需要在模版目录下面创建一个Public目录,并增加一个success.html模版,该页面负责页面的错误或者成功提示并返回。
- <html>
- <
head>
- <
title>页面提示title>
- <
meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <
meta http-equiv='Refresh' content='{$waitSecond};URL={$jumpUrl}'>
head>
- <
body>
- <
TABLE class="message" width="300" align="center" cellpadding=0 cellspacing=0 >
- <
TR class="row" >
- <
th class="tCenter space">{$msgTitle}th>
TR>
- <
present name="message" >
- <
TR class="row">
- <
TD style="color:blue">{$message}TD>
TR>
present>
- <
present name="error" >
- <
TR class="row">
- <
TD style="color:red">{$error}TD>
TR>
present>
- <
present name="closeWin" >
- <
TR class="row">
- <
TD>系统将在 <span style="color:blue;font-weight:bold">{$waitSecond}span> 秒后自动关闭,如果不想等待,直接点击 <A HREF="{$jumpUrl}">这里A> 关闭TD>
TR>
present>
- <
notpresent name="closeWin" >
- <
TR class="row">
- <
TD>系统将在 <span style="color:blue;font-weight:bold">{$waitSecond}span> 秒后自动跳转,如果不想等待,直接点击 <A HREF="{$jumpUrl}">这里A> 跳转TD>
TR>
notpresent>
TABLE>
body>
html>