417 12
发新话题
打印

ThinkPHP入门指南

ThinkPHP入门指南

3.1 简 介
ThinkPHP是一个开源的快速、兼容而且简单的面向对象的轻量级PHP开发框架,ThinkPHP框架致力于简化企业级应用开发过程。

ThinkPHP从Java的Struts结构移植过来,使用面向对象的开发结构和MVC模式,并且模拟实现了Struts的标签库,借鉴了国外一些不错的思想,尤其是Java框架方面,因此熟悉J2EE的开发人员相对比较容易上手,其模版引擎、缓存机制、认证机制和扩展性方面均表现不凡。


在借鉴国外优秀思想的同时,ThinkPHP也更多地考虑了国内的应用开发需要。PHP4兼容、完全支持UTF-8,以及PATHINFO支持等,更加有利于国内的主机环境和开发需要。秉着易用和易扩展的原则,ThinkPHP采用容易理解的项目、模块和操作机制加上内置的一些自动化操作方法,让应用开发变得更加简单,其功能可以通过基类库以及各种插件的形式灵活扩展,从而满足日益增长的业务需求。正是因为具备良好的开发结构,使得ThinkPHP在开发大型应用的时候并不会显得有很多障碍,基于构件的方式,以及配合框架的项目管理机制同样可以让你在处理大型应用的时候一展所长。
ThinkPHP目前版本已经稳定,已经有很多基于ThinkPHP的应用项目,官方文档手册目前仍然处于不断完善中~

TOP

3.2 环境要求
ThinkPHP可以支持WIN/Unix服务器环境,支持PHP4.3.0以上版本,完全兼容PHP5。
支持Mysql、MsSQL、Sqlite等多种数据库,ThinkPHP框架本身没有什么特别模块要求,具体的应用系统运行环境要求视开发所涉及的模块。
提醒:目前的测试表明ThinkPHP在CGI模式和IIS下面的支持有待完善,如果你需要在上面的环境中开发,最好不要使用PATHINFO模式。

如果您在测试和开发ThinkPHP的过程中遇到问题,可以考虑用官方推荐的WAMP5进行环境测试。

TOP

3.3 主要特性
框架模式
ThinkPHP作为一个开源的应用开发框架,借鉴了国外一些优秀框架的思想,融合了Struts的实现和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式,Dao模式中封装了CURD和一些常用操作,单一入口模式等,以及多类型缓存支持,多格式配置支持,所有这一切,让应用开发和运行更有效率。


兼容PHP4和PHP5
ThinkPHP在兼容PHP4和PHP5方面完成出色,除了兼容函数的实现、对架构函数和析构函数的支持外,并且还模拟了一些PHP5具备的优秀特性,例如SPL的部分类型实现。


PATHINFO
ThinkPHP提供了对搜索引擎友好的充分支持,默认的Dispatch器会把所有的GET方式传值转换成PATHINFO形式,并且会把PATHINFO参数转换成GET数组变量,让您可以保持以前的传值和链接形式,转换的工作由框架来完成。您还可以关闭PATHINFO形式,甚至还支持自定义的PATHINFO格式,让你的URL富有创造性。


抽象数据库访问层
ThinkPHP内置了一个抽象数据库访问层,支持包括MySQL、MySQLi、PgSQL、Sqlite、Mssql和Oracle等多种数据库,并且可以通过插件方式扩展。


权限认证
ThinkPHP框架内置了基于RBAC方式的权限认证机制,并且通过ThinkPHP框架的管理后台可以方便地进行授权节点(包括项目、模块和操作)的创建和授权操作。


独特的类库导入机制
ThinkPHP采用类似命名空间方式的导入机制让导入文件变得更加简单,给熟悉Java和.Net的开发人员更加熟悉的类库导入方法import(using 是另外一个别名),例如导入某个工具类Import("Think.Util.ListIterator") 以及目录的导入Import("Think.Core.*"),内建的导入缓存支持避免重复的文件导入。
ThinkPHP基类库提供了很多的实用类库,让应用开发更加方便。
通过模版引擎的标签库功能可以使用html:import标签可以方便导入JS类库和CSS文件
例如:
加载Js类库 < html:import type="js" file="Js.Ajax.ThinkAjax" />
加载CSS文件 < html:import type="css" file="CSS.common" />


国际化支持
在国际化支持方面,ThinkPHP表现也令人满意。首先,UTF-8的支持和自动输出编码转换的实现让页面表现更加满意,另外项目语言包功能保证了应用的多语言支持。还内置了简繁转换插件。


模版引擎
ThinkPHP内置了一个性能卓越的模板引擎,是一个使用了XML标签库技术的编译型模板引擎,支持两种类型的模板标签,使用了动态编译和缓存技术,而且支持自定义标签库,利用该模板引擎可以方便地定义模板文件,从而达到快速开发的目的。现在,通过插件方式还可以灵活地选择你喜欢的模版引擎。


缓存机制
ThinkPHP在数据缓存方面包括SQL查询缓存、数据对象缓存、静态页面缓存以及浏览器缓存等多种机制,采用了包括文件方式、共享内存方式和数据库方式在内的多种方式进行缓存,让应用开发可以选择更加适合自己的缓存方式,从而有效地提高应用执行效率。


插件支持
ThinkPHP的插件机制,让应用开发的扩展性得到充分的加强,或者你很希望Smarty模版引擎作为你的框架模版支持,也许你想增加其他的数据库支持,又或许你想动态的增加一个模块或者操作,通过ThinkPHP的插件功能可以让所有这些实现变得更加轻而易举,而且不用修改框架源文件,免去升级的不便。


Ajax支持
ThinkPHP内置SmartAjax和ThinkAjax类库,对Ajax提供良好支持。支持HTML事件绑定、表单提交、附件上传和定时执行等Ajax操作。


这些特性的综合应用,可以更方便和快捷的开发和部署应用,任何PHP应用开发都可以从ThinkPHP的简单、兼容和快速的特性中受益。更加详细的功能特性会在具体的章节中具体描述。

TOP

3.4 基础概念
在ThinkPHP的学习过程中,需要首先掌握一些基础概念。包括对面向对象和MVC模式的了解,以及ORM、VO等名词的熟悉。
目 录 1. 什么是PHP 2. 什么是面向对象编程 3. 什么是MVC模式 4. 什么是ORM 5. 什么是VO 6. 什么是DAO 7. 什么是VOLIST 8. 什么是HashMap对象

TOP

3.5 目录结构
经过几次调整和优化,ThinkPHP的目录结构已经变得非常清晰和容易部署。大致的目录结构如下:
┎━ThinkPHP 框架系统目录
┃ ┝ Common 公共文件目录
┃ ┝ Lang 系统语言包目录
┃ ┝ PlugIns 公共插件目录
┃ ┗ Lib 应用类库目录
┃ ┝ Think 系统运行库目录(必须)
┃ ┗ ORG 扩展ORG类库包(非必须)

┝━App 项目目录
┃ ┝ Cache 模版缓存目录
┃ ┝ Common 公共文件目录
┃ ┝ Conf 项目配置目录
┃ ┝ Html 静态文件目录
┃ ┝ Lib 应用类库目录
┃ ┝ PlugIns 项目插件目录
┃ ┝ Tpl 项目模版文件目录
┃ ┝ Lang 项目语言包目录
┃ ┝ Logs 项目日志文件目录
┃ ┝ Temp 数据缓存目录
┃ ┗ Uploads 上传文件目录

┃…更多项目目录(和App目录类似,每个项目采用独立目录,便于部署)

┝━Public 网站公共目录(多项目公用)
┃ ┝ Js JS类库目录(建议)
┃ ┝ Images 公共图像目录(建议)
┃ ┗ Uploads 公共上传目录(建议)


其中ThinkPHP系统目录和App目录都可以部署在非WEB目录下面,在WEB目录下面可以仅仅放置项目入口文件和网站公共目录(如Public目录),关于项目入口文件的定义后面会仔细讲述。

如果在类Linux环境下面部署,需要对以下目录设置可写权限(这些目录仅仅针对项目目录,系统目录无需设置任何可写权限,因为每个项目的模版缓存和数据缓存,以及日志文件都是独立的):
项目目录下面的Cache(模版缓存目录)、Temp(数据缓存目录)、Conf(项目配置目录,写入权限用于自动生成配置缓存和插件缓存文件)、 Logs(日志文件目录)、如果设置了Uploads作为上传目录的话该目录也必须设置为可写。
另外,如果设置了Public目录下面的Uploads目录作为公共上传目录,也需要设置可写权限。通常的设置都是设置目录属性为777。
如果要使用后台管理的项目自动创建功能,请设置网站根目录的属性为777,以便系统自动生成项目文件。

TOP

3.6 执行过程
ThinkPHP的分层架构采用三层架构模式:
表现层:包含模板视图、用户界面、JS、Flash等通过模板引擎的支持,可以使用标签定义简化表现层的定义工作。

业务层:包含业务接口层、业务逻辑层、实体层、数据访问层 Action控制器作为业务接口层,提供系统各种业务操作的入口。因此,不提倡在控制器类中写过多的业务逻辑代码,虽然说很难严格控制。具体的业务逻辑应该封装到数据访问对象(Dao)类中实现,如果觉得过于复杂,还可以把子业务在Helper类中包装后统一调用。业务处理过程一般会构造出业务实体对象(如Vo对象),对业务实体对象的存取通过数据访问层完成。数据访问层把实体对象和数据库数据之间建立映射关系,并且封装了通用的数据操作。

数据层:目前支持的数据库有MySql、MsSql、PgSql、Oracle和Sqlite,数据库的选用和业务逻辑没有关系。


基于ThinkPHP框架的应用程序组成和执行过程,如图所示:


说明:
在ThinkPHP中,系统会根据当前的URL来分析要执行的模块和操作。
这个分析工作由URL调度器来实现,官方内置了一个ThinkDispatcher插件来完成该调度。在ThinkDispatcher调度器中,会根据
  • http://servername/appName/modeulName/actionName/params


来获取当前需要执行的项目(appName)、模块(moduleName)和操作(actionName),在某些情况下,appName可以不需要(通常是网站的首页,因为项目名称可以在入口文件中指定,这种情况下,appName就会被入口文件替代)
每个模块名称是一个Action文件,系统会自动寻找项目类库Action目录下面的相关类,如果没有找到,会在加载的插件中寻找是否存在该模块插件,如果依然没有,则抛出异常。
而actionName操作是首先判断是否存在模块的操作方法,如果不存在则会继续寻找父类中的方法,如果没有会尝试寻找插件操作方法,如果依然不存在,那么会寻找是否存在自动匹配的模版文件。如果存在模版文件,那么就直接渲染模版输出。

TOP

3.7 安装和配置
ThinkPHP框架本身无需安装,包含在下载包中的示例项目需要有少许的安装过程,包括数据库的导入和项目部署等。
本章带你了解ThinkPHP的各种配置定义方式和框架的一些配置项目。

ThinkPHP还在不断完善,让项目配置更加方便快捷。目前版本已经支持在后台管理项目配置项目。
目 录 1. 入口文件定义 2. 项目配置 3. 配置参数参考

TOP

3.8 数据模型
在之前的项目配置中我们已经知道了如何定义项目入口文件和进行项目配置,相当于是策划项目的过程。定义数据模型其实就是设计数据结构的过程,把设计好的数据字典转换成对应的数据对象(VO对象)就行了。

Vo对象的定义基于数据表的字段,但是不完全等同于数据表,有如下几点需要注意:
1、在有些环境下面对数据表中的字段是不区分大小写的,但是Vo对象的属性定义是严格区分大小写的,忠于数据表的字段名称是一个好的建议,这样便于移植;
2、Vo对象除了可以包含数据表中对应的字段还可以包括扩展的业务逻辑属性;
3、Vo对象可以包含对视图的定义;
4、为了让数据定义尽量简单化,没有在Vo对象中加入对数据类型、长度和自动增长等设置的定义,但是Vo对象保留了一个特殊属性_info来支持以后的扩展定义。


创建Vo类
我们来根据数据表来创建Vo对象类,假设有个用户表的数据结构为:
  • CREATE TABLE `user` (
  •    `id` int(10) NOT NULL auto_increment,
  •    `name` varchar(30) NOT NULL,
  •    `password` varchar(32) NOT NULL,
  •    `nickname` varchar(30) NOT NULL,
  •    `status` tinyint(1) NOT NULL,
  •    `remark` varchar(255) default NULL,
  •    PRIMARY KEY  (`id`),
  •    UNIQUE KEY `name` (`name`)
  • )



那么我们把user表转换为Vo对象应该写成:
  • class UserVo extends Vo
  • { //类定义开始
  • var $id;                    //用户编号
  • var $name;              //用户名
  • var $password;       //密码
  • var $nickname;        //昵称
  • var $status;             //用户状态
  • var $remark;  //备注信息
  • }//类定义结束



Vo类的文件名和类名同名,例如上面的类文件名应该是 UserVo.class.php,通常放置在项目应用类库目录下面的Vo子目录下面。
注意:上面的写法是兼容PHP4的写法,如果你采用PHP5开发,并且不考虑兼容性的话,可以使用public/protected/private 访问控制符号来定义字段属性。严格来说,Vo对象属性并不一定限制为数据表字段,我们可以理解为视图对象,这样Vo的字段就更加灵活了。
这里定义的Vo对象的属性应该就是数据库查询的返回字段名,如果进行关联查询的话,属性名可能和真实表字段名有所区别。如果你的数据库支持视图,那么这么这里可以定义为视图中字段名。
数据表中字段在某些情况下是不区分大小写的,但是在Vo对象中定义的属性是区分大小写的,这点尤其要注意。
要初始化一个Vo对象可以使用数组或者Map对象,也可以创建空对象,然后进行属性设置。
你不需要为每个对象属性添加存取方法,要获取或者设置Vo对象的属性请使用get和set方法,这两个方法调用了Base基类的__get和__set方法。
创建Vo对象示例:
  • $vo = new UserVo();
  • $vo->set('nickname','流年');
  • // 或者使用
  • $vo->nickname = '流年';



Vo对象有三个转换方法可以转换成其他类型
  • toArray 转换成数组
  • toMap 转换成Map对象
  • toJson 转换成Json字串


可以使用isEmpty方法判断一个Vo对象是否为空。
在ThinkPHP开发模型中默认的数据表主键命名统一使用id,并且使用自动增长类型,如果和你的数据库设计不符,在使用Dao类的时候需要设置参数。
另外一个高级技巧是可以为多个Vo对象定义父类,那么通过相关设置,你可以做到更新子对象的同时可以更新父对象。
例如,为网站的所有类型的用户定义一个UserVo对象,其中包括了所有类型用户所公共的属性,各类型的私有属性可以定义在自己的Vo对象中,如下面的会员Vo对象继承了UserVo对象
  • class MemberVo extends UserVo
  • { //类定义开始
  • //父类中的属性无需再定义了
  • //这里添加会员才有的一些属性
  • var $email;          //邮箱
  • var $tel;              //电话
  • var $birthday;     //生日
  • var $nickname;   //昵称
  • }//类定义结束



如果Member数据表和User数据表在你的数据库设计中都存在,那么,你可以设置项目配置文件中的SAVE_PARENT_VO 和UPDATE_PARENT_VO参数来实现保存和更新子表的同时操作父表。

最新的版本支持Vo类的自动创建,具体请参考高级指南部分的说明。

如果要进行关联数据的查询,需要在Vo类里面定义$_link 属性,该部分的具体定义同样在高级指南里面进行说明。

TOP

3.9 控制器
在定义了数据模型之后,就可以开始定义模块和相关的操作了,暂时我们还不用关心领域逻辑和业务实现。因为ThinkPHP框架基于模块和操作进行访问,因此规划好系统的模块和操作很关键,也就是设计Action控制器。数据对象Vo是对应一个数据表或者视图的,而模块操作并不一定对应某个数据表,并且Action控制器是不直接操作Vo对象的,而是通过数据访问对象Dao来操作的。

Action控制器的定义非常简单,每个Action控制器就是一个Action类的子类。类中的每个方法(不包括内部方法)就定义了一个相关操作。
标准的操作访问URL应该是下面的格式:
http:///moduleName/actionName/id/2

如果定义了一个list(列表)操作,那么访问该操作的URL地址是
http:///user/list/

如果还定义了编辑操作edit,那么编辑一个id为2的user的访问地址是
http:///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('jumpUrl',__URL__.'/list/');
  •      $this->success('新增成功');
  •   }else {
  •       //失败提示
  •        $this->error('新增失败');
  •   }
  • }



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对象缓存,保证在系统使用缓存动态数据的情况下用户也能及时看到数据修改。

TOP

3.10 数据访问
业务逻辑一般都是对数据的访问和操作,为了兼容性考虑,ThinkPHP框架没有使用Adodb或者PDO(PHP5才内置支持)作为抽象数据库访问层,而是内置实现了一个抽象数据库访问层,当然这个抽象层的实现上也参考了部分目前比较先进的抽象数据库访问层框架,并且会保持不断完善。

ThinkPHP的抽象数据库访问层主要包含了数据库公共类、各类数据库驱动类和数据集对象。在实际应用开发过程中,你可能并不需要接触这些类库,只需要通过各自的Dao对象来访问和操作数据库就可以,Dao对象处于抽象数据库访问层的上层,属于业务逻辑的实现层。数据库操作类库的主要特点有:
1、 支持事务和回滚(当然首先需要数据库本身支持),但是默认是自动提交
2、 在数据库调试模式下支持SQL语句的输出
3、 完全支持中文UTF-8字符集
4、 把查询操作和执行操作分开,便于返回不同的结果
5、 支持配置文件和DSN两种数据库配置读取方式
6、 支持对数据集的数组和对象两种方式返回

数据库类库中最重要就是公共类Db的实现,除了引导各种数据库驱动之外,它还提供了数据库抽象访问的一些基本方法,包括CURD的SQL指令的抽象访问。查询的结果返回数据集对象ResultSet,而Dao对象把查询的数据集从数据集对象又转换成了Vo对象或者VoList对象。最终的目的是为了让应用操作数据库更加方便有效。

抽象数据库访问层的关键类库在于数据库的公共访问类Db类,这个类是操作数据库的底层接口,换句话说,Db类不能够独立存在,必须有对应的数据库驱动类库,但是开发人员不能够跨过该类直接进行数据库操作的访问。目前系统支持的数据库包含有MySQL、MySQLi、MsSQL、PgSQL、SqLite和Oracle,可以通过插件方式增加自己需要的数据库驱动,开发人员也可以按照规范编写自己的数据库驱动(甚至包括众多的嵌入式数据库的驱动)。
注意:最新的版本已经加入PDO的支持。

数据库的配置文件有多种定义方式:
第一种 在每个应用的配置文件中定义
  • //数据库设置
  • define('DB_TYPE', 'mysql');
  • define('DB_HOST', 'localhost');
  • define('DB_NAME','web');
  • define('DB_USER','root');
  • define('DB_PWD','');
  • define('DB_PORT','');



系统推荐使用该种方式,因为一般一个应用的数据库访问配置是相同的。
第二种 使用DSN方式在初始化Db类的时候传参数
  • $db_dsn = “mysql://username:passwd@localhost:3306/DbName”;
  • $db = new Db($db_dsn);



第三种 使用数组传参数
  • $DSN = array(
  • 'dbms'     => 'mysql',
  • 'username' => 'username',
  • 'password' => 'password',
  • 'hostname' => 'localhost',
  • 'hostport' => '3306',
  • 'database' => 'dbname'
  • );
  • $db = new Db($DSN);



在初始化数据库公共类的时候,会根据dbms的值来定位数据库类型,并进行数据库连接,如果数据库驱动不存在或者连接失败,会抛出异常。
Db类的查询结果保存在数据集对象ResultSet中,并且支持数据查询的缓存操作。为了更加方便和直观,ThinkPHP还在抽象数据库访问层之上,构建了一个数据访问对象(Dao),采用了简单的OO-RDBMS mapping机制,把数据集对象ResultSet转换成Vo对象或者VoList对象,可以把数据表的一条记录看成是一个Vo对象实例,对数据表的任何操作都是对Vo对象的操作。
关于Dao类的具体操作,请参考类库参考里面的Dao类使用。

数据访问对象类中还实现了ResultSet对象的转换,把Db类中的查询结果转换成Vo或者VoList对象(这样的好处有很多,最起码知道自己在操作什么数据表,而不是和枯燥的数据集对象打交道,也便于模板引擎的输出)。
数据访问对象类中另外一个非常实用的方法就是CreateVo方法,这个方法能够根据表单提交的数据自动创建出一个Vo对象。
  • $dao = new UserVo();
  • $user = $dao->createVo();


如果是编辑状态,那么需要使用createVo来获取编辑页面提交的Vo对象。
  • $user = $dao->createVo('edit');



数据缓存
ThinkPHP框架从0.8版本开始支持动态数据缓存,之前已经实现了模板缓存。
ThinkPHP的动态数据缓存有三层实现,第一层是Db类的查询数据集缓存,这层缓存是基于SQL指令的;第二层是由Dao类实现的Vo对象和VoList对象的缓存,这层缓存是基于Vo对象和分页VoList对象的;第三层是由控制器类实现的,在数据更新的时候能够自动更新Vo对象缓存,由于某些特殊原因,目前还没法支持VoList对象的缓存更新。
定义一个Dao类非常简单,对于某些应用,你甚至只需要定义一个空的Dao基础类的子类就可以了。

class UserDao extends Dao { }
一个简单的Dao方法定义如下:
  • function forbid($condition,$table)
  •     {
  •         if(FALSE === $this->db->execute('update '.$table.' set status=0 where status=1 and ('.$condition.')')){
  •             return false;
  •          }else {
  •             return True;
  •          }
  •      }



Dao类中提供了对事务的支持,如果要使用事务操作,可以通过下面的方法
  • startTrans()
  • commit()
  • rollback();

TOP

 417 12
发新话题