在
定义了数据模型之后,就可以开始定义模块和相关的操作了,暂时我们还不用关心领域逻辑和业务实现。因为
ThinkPHP框架基于模块和操作进行访问,因此规划好
系统的模块和操作很关键,也就是设计Action控制器。数据对象Vo是对应一个数据表或者视图的,而模块操作并不一定对应某个数据表,并且Action控制器是不直接操作Vo对象的,而是通过数据访问对象Dao来操作的。
Action控制器的定义非常简单,每个Action控制器就是一个Action类的子类。类中的每个方法(不包括内部方法)就定义了一个相关操作。
标准的操作访问URL应该是下面的格式:
http://<serverName>/moduleName/actionName/id/2
如果定义了一个list(列表)操作,那么访问该操作的URL地址是
http://<serverName>/user/list/
如果还定义了编辑操作edit,那么编辑一个id为2的user的访问地址是
http://<serverName>/user/edit/id/2
下面我们来看下具体的操作实现方法。
操作一般可以分为可视操作和不可视操作,对于可视操作,一般都需要定义
模板。举个简单的例子,要增加用户,必须定义增加(add)操作和保存(insert)操作,add操作是用于用户数据录入,属于可视操作,需要定义一个增加用户的表单
页面模板,而insert操作是用于数据提交并保存
数据库,其中可能包含一些验证,这些操作都属于后台实现,不需要模板支持,因此这类操作就属于不可视操作,如果实现了动作链的话,可以把这几个操作连接起来,但是本质上还是有多个操作组成的。
例如我们定义了一个UserAction控制器,类名是模块名+Action方式组成。
- class UserAction extends Action { }
控制器类继承自ThinkPHP基类库的Action类,这样的实现是为了方便加载系统自带的模板
引擎,并且可以继承Action类的一些通用操作。如果你不需要这些功能(例如,你打算采用
Smarty或者自己的模板引擎、你觉得系统Action类的方法根本用不上等等),那么完全可以不用基于Action扩展。类可以完全独立编写,但是为了兼容性考虑,建议继承Base类。
类的
文件名应该和类名相同(注意大小写),并且使用.class.php作为后缀,放置在
项目应用类库下面的Action目录,每个文件应该只定义一个模块类。
我们来定义第一个list操作,用于显示用户列表
funtion list()
操作方法的实现不需要添加参数
为了取得用户列表,我们需要通过数据库查询所有的用户数据并显示。
我们之前可能已经定义了一个UserVo对象,要操作UserVo对象,我们一般是通过UserDao对象,UserDao对象的定义放到下一章节讲述,暂且先不考虑。我们只是使用该UserDao对象。
首先引入UserDao类库
Import ("@.Dao.UserDao");
如果对import方法还不清楚,请参考前面部分。
定义Dao对象
$dao = new UserDao();
用findAll方法获取全部用户列表
$userList = $dao->findAll();
$userList 取得的是一个VoList对象,可以方便的通过ThinkPHP模板引擎定义的Volist标签来输出用户列表,控制器所要做的仅仅是告诉模板引擎我要输出什么东西
$this->assign('userList',$userList);
因为Action类已经内置了对ThinkPHP模板引擎的支持,所以不需要再定义和初始化模板类,如果你的控制器类没有继承自Action,那么可以使用下面语句
$tpl =
Template::getInstance();
$tpl->assign('userList',$userList);
不管要输出什么类型的
变量,统一使用assign方法给模板赋值(注:早期的FCS版本对Vo和VoList类型需要使用不同的赋值方法,现在已经统一,全部有模板引擎来解析)。
接下来关键的一步就是显示页面,上面的操作仅仅是赋值给模板,但是并没有告诉模板引擎我要输出页面。要输出页面,使用
$this->display();
该语句会加载当前模块操作的默认模板页面,所以无需指定模板文件。其实display方法有三个参数,可以实现很多功能。
$templateFile 当前操作的模板文件,默认自动加载
$varPrefix 输出模板变量的前缀,默认为空
$charset 输出页面的字符集 默认为配置文件中的OUTPUT_CHARSET设置
这样,list操作就完成了,在
浏览器的地址栏输入
http://<serverName>/user/list/
系统就会定位到UserAction的list方法,并且在执行display方法的时候调用相关模板文件完成页面输出。至于具体的模板文件的定义,后面会详细描述。
上面的方法实现了一个简单的用户列表功能,完整代码如下
- function list(){
-
Import ("@.Dao.UserDao");-
$dao = new UserDao();-
$userList = $dao->findAll();-
$this->assign(‘userList’,$userList);-
$this->display();- return ;
- }
要实现add操作比list操作更加简单,因为没有任何变量要赋值给模板,要做的仅仅是调用模板显示
- function add(){$this->display();
- return ;
- }
要保存表单录入数据,需要定义insert操作,来把用户信息保存到数据库。
- function insert(){
-
Import ('@.Dao.UserDao');-
$dao = new UserDao();-
$vo = $dao->createVo();-
$result = $dao->add($vo);- if (
$result){-
//成功提示-
$this->assign('message','新增成功');-
$this->assign('jumpUrl',__URL__.’/list/’);- }else {
-
//失败提示-
$this->assign('msgType','error');-
$this->assign('message','新增失败');- }
-
//页面跳转-
$this->forward();- }
Dao对象的createVo方法可以根据表单的提交值创建UserVo对象,然后调用Dao对象的add方法把Vo对象保存到数据库。这样用户信息的保存操作就完成了。
一般在数据保存后会给出提示信息,并进行页面跳转,(
Ajax实现不包含此范畴)
forward方法就是起这个作用,会根据相关的信息进行页面跳转,需要设置的值包括
message 提示信息
msgType 提示类型 error表示错误,默认为成功
jumpUrl 要跳转的url地址,默认失败返回前页,成功后返回模块列表页面
ajaxReturn 用于Ajax操作的数据返回
是否觉得这样的方式很方便呢,但是ThinkPHP为您考虑得更周到,系统为您封装了一些通用的实现操作,并且很容易的扩展和继承,让您在Action控制器实现上面更加简单。
目前为止,系统Action类封装的通用操作有:
- index默认的列表操作
- add 默认的新增操作
- insert 默认的新增保存操作
- edit 默认的编辑操作
- update 默认的编辑保存操作
- delete 默认的删除操作
- verify 默认的显示验证码操作
- download 默认的文件下载操作
- delAttach 默认的删除附件操作
- output 默认的导出列表数据操作
- forbit 默认的禁用操作
- resume 默认的恢复操作
不要认为系统封装的这些方法仅仅是一个简单通用的封装,其实还实现了更加强大的功能。
- 1、支持Dao对象自动导入,不需要手动引入需要的Dao类库,系统自动判断当前Action控制器来加载对应的Dao对象。
- 2、默认的列表操作支持列表排序、搜索,并且你可以重载实现搜索的方法,并且支持过滤器方法,你只需要在自己的Action控制器中声明_filter方法就可以在页面搜索的前提下实现后端过滤。
- 3、支持验证,只要在自己的Action控制器中声明_validation方法就可以在表单提交的时候实现自动验证(这里指后台验证,前端验证由JS实现)。
- 4、支持表单预操作,只要在自己的Action控制器中声明_operation方法就可以在表单提交的时候对表单数据进行预先处理,或者添加表单中没有的元素。
- 5、支持附件上传,系统的insert和update方法会自动检测是否有附件上传,如果存在就会自动保存附件信息。并且在edit操作中已经取得了当前vo对象的附件列表,可以直接在模板页面输出。
- 6、支持触发器,如果定义了自己的_trigger方法,那么可以实现在保存数据后进行一些其他关联操作。
- 7、支持更新缓存,系统在更新数据后,会自动更新对应的Vo对象缓存,保证在系统使用缓存动态数据的情况下用户也能及时看到数据修改。