# 驱动扩展
[上一页](# "上一页")[下一页](# "下一页")
这里说的驱动扩展是一种泛指,驱动扩展的目录位于扩展目录Extend/Driver,包括数据库驱动、缓存驱动、标签库驱动和模板引擎驱动。
### 数据库驱动
数据库抽象层的设计是由抽象数据库类(Db)和数据库驱动类组成的,内置的数据库驱动是MySQL和MySQLi驱动类,官方的扩展还提供了MsSQL、PgSQL、Sqlite、Oracle、Ibase、Mongo以及PDO驱动类,可以满足常用的数据库操作的需要。
数据库驱动扩展目录位于系统扩展目录Extend/Driver/Db,如果需要扩展其他的数据库驱动类,只需要继承Db类,驱动类的命名规范是:
Db+驱动类名称(首字母大写)
例如,假如你需要扩展一个ODBC的数据库驱动,应该命名为:DbOdbc.class.php,并放到系统扩展目录 Extend/Driver/Db目录下面。`Class DbOdbc extends Db{
}`每个数据库驱动必须要实现的方法包括(具体参数可以参考现有的数据库驱动类库):
| 驱动方法 | 方法说明 |
|-----|-----|
| 架构方法 | __construct($config='') |
| 数据库连接方法 | connect($config='',$linkNum=0,$force=false) |
| 释放查询方法 | free() |
| 查询操作方法 | query($str) |
| 执行操作方法 | execute($str) |
| 开启事务方法 | startTrans() |
| 事务提交方法 | commit() |
| 事务回滚方法 | rollback() |
| 获取查询数据方法 | getAll() |
| 获取字段信息方法 | getFields($tableName) |
| 获取数据库的表 | getTables($dbName='') |
| 关闭数据库方法 | close() |
| 获取错误信息方法 | error() |
| SQL安全过滤方法 | escapeString($str) |
数据库的CURD接口方法(通常这些方法无需重新定义)
| 方法 | 说明 |
|-----|-----|
| 写入 | insert($data,$options=array(),$replace=false) |
| 更新 | update($data,$options) |
| 删除 | delete($options=array()) |
| 查询 | select($options=array()) |
介于不同数据库的查询方法存在区别,所以经常需要对查询的语句进行重新定义,这就需要修改针对查询的selectSql属性。该属性定义了当前数据库驱动的查询表达式,默认的定义是:
'SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%'
驱动可以更改或者删除个别查询定义,或者更改某个替换字符串的解析方法,这些方法包括:
| 方法名 | 说明 | 对应 |
|-----|-----|-----|
| parseTable | 数据库表名解析 | %TABLE% |
| parseWhere | 数据库查询条件解析 | %WHERE% |
| parseLimit | 数据库查询Limit解析 | %LIMIT% |
| parseJoin | 数据库JOIN查询解析 | %JOIN% |
| parseOrder | 数据库查询排序解析 | %ORDER% |
| parseGroup | 数据库group查询解析 | %GROUP% |
| parseHaving | 数据库having解析 | %HAVING% |
| parseDistinct | 数据库distinct解析 | %DISTINCT% |
| parseUnion | 数据库union解析 | %UNION% |
| parseField | 数据库字段解析 | %FIELD% |
驱动的其他方法根据自身驱动需要和特性进行添加,例如,有些数据库的特殊性,需要覆盖父类Db类中的解析和过滤方法,包括:
| parseKey | 数据库字段名解析 |
|-----|-----|
| parseValue | 数据库字段值解析 |
| parseSet | 数据库set分析 |
| parseLock | 数据库锁机制 |
定义了驱动扩展后,需要使用的时候,设置相应的数据库类型即可:`'DB_TYPE'=>'odbc', // 数据库类型配置不区分大小写`
### 缓存驱动
系统的缓存实现是由缓存类和缓存驱动组成,缓存驱动扩展位于Extend/Driver/Cache目录下面,目前已经提供了包括APC、Db、Memcache、Shmop、Sqlite、Redis、Eaccelerator和Xcache缓存方式的驱动扩展,缓存驱动必须继承Cache类,缓存驱动类的命名规范是:
Cache+驱动类名称(首字母大写)
并实现下面的驱动接口:
| 方法说明 | 接口方法 |
|-----|-----|
| 架构方法 | __construct($options='') |
| 读取缓存 | get($name) |
| 写入缓存 | set($name,$value,$expire=null) |
| 删除缓存 | rm($name) |
| 清空缓存 | clear() |
注意:有些缓存方式并未提供清空缓存接口,可以无需定义。
所有缓存驱动的有效期参数约定,如果设置为0 则表示永久缓存。如果要让缓存驱动支持缓存队列功能,需要在缓存接口的set操作方法设置成功后添加如下代码:`if($this->options['length']>0) {
// 记录缓存队列
$this->queue($name);
}`
### Session驱动
新版支持对session 的hander驱动,可以通过驱动更改session的管理机制。Session驱动扩展目录位于Extend/Driver/Session下面,命名规范是:
Session+驱动类名称(首字母大写)
并实现下面的驱动接口:
<table border="0" cellspacing="1" cellpadding="0"><tr><th>方法说明</th> <th>接口方法</th> </tr><tr><td>执行入口</td> <td>execute()并且在方法中调用session_set_save_handler函数指定hander操作机制</td> </tr><tr><td colspan="2">并建议添加下面的接口方法</td> </tr><tr><td>打开Session</td> <td>open($savePath,$sessionName)</td> </tr><tr><td>关闭Session</td> <td>close()</td> </tr><tr><td>读取Session</td> <td>read($id)</td> </tr><tr><td>写入Session</td> <td>write($id,$data)</td> </tr><tr><td>删除Session</td> <td>destory($id)</td> </tr><tr><td>Session过期回收</td> <td>gc($maxlifetime)</td> </tr></table>
### 标签库驱动
任何一个模板引擎的功能都不可能是为你量身定制的,具有一个良好的可扩展机制也是模板引擎的另外一个考量,Smarty采用的是插件方法来实现扩展,ThinkTemplate由于采用了标签库技术,比Smarty提供了更为强大的定制功能,和Java的TagLibs一样可以支持自定义标签库和标签,每个标签都有独立的解析方法,所以可以根据标签库的定义规则来增加和修改标签解析规则。在ThinkTemplate中标签库的体现是采用XML命名空间的方式。
每个标签库对应一个标签库驱动类,每个驱动类负责对标签库中的所有标签的解析。标签库驱动类的作用其实就是把某个标签定义解析成为有效的模版文件(可以包括PHP语句或者HTML标签)。
系统的标签库驱动扩展目录位于Extend/Driver/TagLib目录下面,命名规范是:
TagLib+标签库名称(首字母大写)
目前已经提供了Html标签库驱动支持,标签库驱动扩展必须继承TagLib类,例如我们扩展一个Test标签库:`Class TagLibTest extends TagLib{}`首先需要定义标签库的标签定义,标签定义包含了所有标签库中支持的所有标签,定义方式如下:`protected $tags = array(
// 定义标签
'input'=>array('attr'=>'type,name,id,value','close'=>0), // input标签
);`标签库的所有支持标签都在tags属性中进行定义,tags属性是一个二维数组,每个元素就是一个标签定义,索引名就是标签名,采用小写定义,调用的时候不区分大小写。
每个标签定义支持的属性包括:
| 属性名 | 说明 |
|-----|-----|
| attr | 标签支持的属性列表,用逗号分隔 |
| close | 标签是否为闭合方式 (0闭合 1不闭合),默认为不闭合 |
| level | 标签的嵌套层次(只有不闭合的标签才有嵌套层次) |
| alias | 标签别名 |
定义了标签属性后,就需要定义每个标签的解析方法了,每个标签的解析方法在定义的时候需要添加“_”前缀,可以传入两个参数,属性字符串和内容字符串(针对非闭合标签)。必须通过return 返回标签的字符串解析输出,在标签解析类中可以调用模板类的实例。下面是一个input解析方法的定义:
`public function _input($attr,$content) {
$tag = $this->parseXmlAttr($attr,'input');
$name = $tag['name'];
$id = $tag['id'];
$type = $tag['type'];
$value = $this->autoBuildVar($tag['value']);
$str = '';
return $str;
}`在每个标签的解析方法中,首先需要调用` $this->parseXmlAttr($attr,'input');`表示分析input标签的标签定义,并返回input的所有标签属性。接下来就是根据具体的属性值来返回实际的解析内容了。由于是示例,我们没有对标签中的全部变量进行解析,只是支持了value属性的变量传入。
定义好标签库扩展之后,我们就可以在模板中使用了,首先我们必须要告诉模板申明Test标签库,用taglib标签,例如:`<taglib name='Test' />`name属性支持申明多个标签库,用逗号分隔即可。申明Test标签库之后,就可以使用Test标签库中的所有标签库了,调用方式如下:`<test:input type='radio' id='test' name='mail'value='value' />`注意:调用扩展标签库的标签的时候,必须加上标签库的XML命名空间前缀。
由于我们定义的input标签是闭合标签,如果是非闭合方式的话,应该是写成:`<test:input type='radio' id='test' name='mail' value='value'></test:input>`Input标签定义value属性可以支持变量传入,所以value被认为是一个变量名,如果在Action中已经给value模板变量赋值,例如:`$this->assign('value','my test value');`最后标签被模板引擎编译后,就会输出:`<input type='radio' id='test' name='mail' value='my test value'/>`
### 模板引擎驱动
系统支持模板引擎的扩展机制,模板引擎驱动的扩展目录位于Extend/Driver/Template下面,并且命名规范为:
Template+模板引擎名(首字母大写)
模板引擎驱动不需要继承任何类库,并且只需要实现一个接口方法:
<table border="0" cellspacing="1" cellpadding="0"><tr><th>接口说明</th> <th>使用说明</th> </tr><tr><td>渲染模板输出</td> <td>fecth($tempateFie,$var)<br/>tempateFie表示要解析的模板文件名<br/>var表示要传入的模板变量数组</td> </tr></table>
官方目前已经提供了包括Smarty、EaseTemplate、TemplateLite和Smart在内的第三方模板引擎扩展。
模板引擎扩展必须要配合第三方类库一起使用,我们以Smarty模板引擎为例,来说明下如何使用第三方模板引擎。首先,下载最新的Smarty模板引擎文件放到系统目录的Vendor第三方类库目录下面,建立Smarty子目录。
然后,修改项目配置文件,把模板引擎改为扩展的模板引擎名:`'TMPL_ENGINE_TYPE' =>'Smarty'`就可以用smarty标签来定义你的模板文件了,改变模板引擎驱动并不会影响系统内部的模板变量输出和模板文件定位,例如我们在上面提到的用assign赋值模板变量、display和fetch方法的使用、模板文件的定位规则、模板替换功能仍然都可以使用。
对于某些第三方的模板引擎,还可以用TMPL_ENGINE_CONFIG参数进行自定义的配置。
例如对于Smarty模板引擎而言,我们可以进行下面的配置参数定义:`'TMPL_ENGINE_CONFIG'=>array(
'caching'=>true,
'template_dir'=>TMPL_PATH,
'cache_dir'=>TEMP_PATH,
)`一般情况下,无需设置TMPL_ENGINE_CONFIG参数,模板引擎驱动已经有最适合的默认值了。
[上一页](# "上一页")[下一页](# "下一页")
- 序言
- 1. 入门
- 1.1 简介
- 1.2 基础概念
- 1.3 获取ThinkPHP
- 1.4 环境要求
- 1.5 许可协议
- 1.6 目录结构
- 1.7 命名规范
- 1.8 MVC分层
- 1.9 CBD架构
- 1.10 特性概述
- 1.11 系统流程
- 1.12 开发流程
- 2. 入口
- 2.1 入口文件
- 2.2 项目目录
- 2.3 部署目录
- 2.4 项目编译
- 2.5 调试模式
- 3. 配置
- 3.1 配置格式
- 3.2 惯例配置
- 3.3 项目配置
- 3.4 调试配置
- 3.5 分组配置
- 3.6 读取配置
- 3.7 动态配置
- 3.8 扩展配置
- 4. 函数和类库
- 4.1 函数库
- 4.2 类库
- 5. 控制器
- 5.1 URL模式
- 5.2 模块和操作
- 5.3 定义控制器
- 5.4 空操作
- 5.5 空模块
- 5.6 模块分组
- 5.7 URL伪静态
- 5.8 URL路由
- 5.9 URL重写
- 5.10 URL生成
- 5.11 URL大小写
- 5.12 前置和后置操作
- 5.13 跨模块调用
- 5.14 页面跳转
- 5.15 重定向
- 5.16 获取系统变量
- 5.17 判断请求类型
- 5.18 获取URL参数
- 5.19 AJAX返回
- 5.20 Action参数绑定
- 5.21 多层控制器支持
- 6. 模型
- 6.1 模型定义
- 6.2 模型实例化
- 6.3 字段定义
- 6.4 数据主键
- 6.5 属性访问
- 6.6 跨库操作
- 6.7 连接数据库
- 6.8 切换数据库
- 6.9 分布式数据库
- 6.10 创建数据
- 6.11 字段映射
- 6.12 连贯操作
- 6.13 CURD操作
- 6.14 ActiveRecord
- 6.15 自动验证
- 6.16 命名范围
- 6.17 自动完成
- 6.18 查询语言
- 6.19 查询锁定
- 6.20 字段排除
- 6.21 事务支持
- 6.22 高级模型
- 6.23 视图模型
- 6.24 关联模型
- 6.25 Mongo模型
- 6.26 动态模型
- 6.27 虚拟模型
- 6.28 多层模型支持
- 7. 视图
- 7.1 模板定义
- 7.2 模板赋值
- 7.3 模板输出
- 7.4 模板替换
- 7.5 获取内容
- 7.6 模板引擎
- 7.7 布局模板
- 8. 模板引擎
- 8.1 变量输出
- 8.2 系统变量
- 8.3 使用函数
- 8.4 默认值输出
- 8.5 使用运算符
- 8.6 内置标签
- 8.7 包含文件
- 8.8 导入文件
- 8.9 Volist标签
- 8.10 Foreach标签
- 8.11 For标签
- 8.12 Switch标签
- 8.13 比较标签
- 8.14 三元运算
- 8.15 范围判断标签
- 8.16 Present标签
- 8.17 Empty标签
- 8.18 Defined标签
- 8.19 Define标签
- 8.20 Assign标签
- 8.21 IF标签
- 8.22 标签嵌套
- 8.23 使用PHP代码
- 8.24 模板布局
- 8.25 模板继承
- 8.26 原样输出
- 8.27 模板注释
- 8.28 引入标签库
- 8.29 修改定界符
- 8.30 避免JS混淆
- 9. 日志
- 9.1 日志级别
- 9.2 记录方式
- 9.3 手动记录
- 10. 错误
- 10.1 异常处理
- 10.2 异常模板
- 10.3 异常显示
- 11. 调试
- 11.1 运行状态
- 11.2 页面Trace
- 11.3 调试方法
- 12. 缓存
- 12.1 缓存方式
- 12.2 动态缓存
- 12.3 缓存队列
- 12.4 快捷缓存
- 12.5 快速缓存
- 12.6 查询缓存
- 12.7 SQL解析缓存
- 12.8 静态缓存
- 13. 扩展
- 13.1 行为扩展
- 13.2 类库扩展
- 13.3 控制器扩展
- 13.4 模型扩展
- 13.5 驱动扩展
- 13.6 Widget扩展
- 13.7 模式扩展
- 13.8 引擎扩展
- 14. 安全
- 14.1 表单令牌
- 14.2 字段类型验证
- 14.3 防止SQL注入
- 14.4 输入过滤
- 14.5 上传安全
- 14.6 防止XSS攻击
- 14.7 其他安全建议
- 14.8 目录安全文件
- 14.9 保护模板文件
- 15. 性能
- 15.1 关闭调试模式
- 15.2 开启缓存
- 15.3 合并字段缓存
- 15.4 优化SQL
- 15.5 替换入口
- 15.6 前端优化
- 16. 部署
- 16.1 PATH_INFO支持
- 16.2 隐藏index.php
- 16.3 二级域名部署
- 16.4 定制错误页面
- 16.5 设置时区
- 17. SAE支持
- 17.1 SAE介绍
- 17.2 获取SAE
- 17.3 SAE开发
- 18. REST支持
- 18.1 REST介绍
- 18.2 REST模式
- 18.3 REST配置
- 18.4 REST路由
- 18.5 REST方法
- 19. 杂项
- 19.1 Session支持
- 19.2 Cookie支持
- 19.3 日期和时间
- 19.4 WML开发
- 19.5 多语言
- 19.6 数据分页
- 19.7 文件上传
- 19.8 验证码
- 19.9 图片添加水印
- 19.10 IP获取和定位
- 20. 附录
- 20.1 常量参考
- 20.2 配置参考
- 20.3 关于升级
- 20.4 大事记
- 鸣谢
- 关于