### 2019 年 1 月 26 日 发布
>[info] 相信大家一定希望官方能够发布更多的扩展和插件,但事实上这个想法并不现实,随着官方同时维护的扩展越来越多(目前已经参与维护的扩展数量超过36个),很难及时更新和迭代,因此需要大家一起来参与贡献,众人拾柴火焰高,希望大家多参与`ThinkPHP5`的生态,来添砖加瓦。
本篇我们来聊聊应该如何正确的贡献自己的`ThinkPHP5`扩展。
`ThinkPHP`扩展主要包括两种类型:第一种是依赖`ThinkPHP`的(某个版本),比如某个缓存驱动,某个中间件等等,仅用于ThinkPHP开发的项目;第二种是不依赖`ThinkPHP`的独立(功能)类库,这个涉及的范畴比较广,并且可以用于任何项目。
## 遵循规范
无论是哪一种类型的扩展,都应该使用`Composer`包的方式来开发和安装使用(`ThinkPHP5`的官方扩展全部是基于`Composer`安装的)。
如果还不清楚如何制作一个`Composer`包,可以参考这篇:[如何创建一个自己的 Composer 库](https://juejin.im/entry/57d7c3d2a0bb9f0057f244fc)。
>[info] 要注意的是,作为一个规范的`Composer`包,代码风格必须严格遵循`PSR-2`规范和使用`PSR-4`自动加载规范。
独立功能类库没有特别的要求,一般明确PHP的版本要求和其它依赖即可,并选择一个开源协议,然后自己做好测试和添加相关说明(`readme.md`)或者附上文档地址即可,所以不做特别的说明。
## `ThinkPHP`专用扩展
如果是开发`ThinkPHP5`专属的扩展,最好的办法是参考官方的相关扩展进行,但务必注意,针对不同的ThinkPHP版本你需要不同的实现(通常可以采用分支的形式,并依赖不同的框架版本),主要包括:
### 缓存驱动
以ThinkPHP`5.1`版本为例,如果要扩展一个ThinkPHP的缓存驱动,只需要继承系统的缓存驱动基础类`think\cache\Driver`,并实现下面的抽象方法。
```
/**
* 判断缓存是否存在
* @access public
* @param string $name 缓存变量名
* @return bool
*/
abstract public function has($name);
/**
* 读取缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $default 默认值
* @return mixed
*/
abstract public function get($name, $default = false);
/**
* 写入缓存
* @access public
* @param string $name 缓存变量名
* @param mixed $value 存储数据
* @param int $expire 有效时间 0为永久
* @return boolean
*/
abstract public function set($name, $value, $expire = null);
/**
* 自增缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
abstract public function inc($name, $step = 1);
/**
* 自减缓存(针对数值缓存)
* @access public
* @param string $name 缓存变量名
* @param int $step 步长
* @return false|int
*/
abstract public function dec($name, $step = 1);
/**
* 删除缓存
* @access public
* @param string $name 缓存变量名
* @return boolean
*/
abstract public function rm($name);
/**
* 清除缓存
* @access public
* @param string $tag 标签名
* @return boolean
*/
abstract public function clear($tag = null);
```
### 数据库驱动
要支持某个特殊的数据库(包括`NoSQL`数据库),可以参考官方的`Oracle`驱动扩展和`MongoDb`驱动扩展。
* `Oracle`扩展 [topthink/think-oracle](https://github.com/top-think/think-oracle)
* `MongoDb`扩展 [topthink/think-mongo](https://github.com/top-think/think-mongo)
对于PDO支持的数据库驱动,`Oracle`扩展就是一个典型的例子,你通常只需要实现数据库连接驱动(继承系统的`think\db\Connection`类)和数据库解析驱动(继承系统的`think\db\Builder`类)即可。
而对于非PDO支持的数据库,`Mongo`扩展就是一个典型例子,通常你还需要额外实现一个数据库查询驱动类(继承`think\db\Query`类),并且这种情况下,你的数据库连接驱动和解析驱动可以无需继承系统的基类。
### Session驱动
对于`Session`驱动其实很简单,你只需要基于`SessionHandlerInterface`接口实现即可,也就是包含如下方法实现。
```
abstract public close ( void ) : bool
abstract public destroy ( string $session_id ) : bool
abstract public gc ( int $maxlifetime ) : int
abstract public open ( string $save_path , string $session_name ) : bool
abstract public read ( string $session_id ) : string
abstract public write ( string $session_id , string $session_data ) : bool
```
### 日志驱动
ThinkPHP的日志驱动,其实是一个独立的类库,而且只需要实现一个`save`方法,可以参考官方的[`SeasLog`](https://github.com/top-think/think-seaslog)驱动实现。
```
/**
* 日志写入接口
* @access public
* @param array $log 日志信息
* @param bool $append 是否追加请求信息
* @return bool
*/
public function save(array $log = [], bool $append = false): bool
```
### Trace驱动
ThinkPHP的页面Trace驱动也是一个独立的类库,只需要实现一个`output`方法。
```
/**
* 调试输出接口
* @access public
* @param Response $response Response对象
* @param array $log 日志信息
* @return bool|string
*/
public function output(Response $response, array $log = [])
```
### 模板引擎扩展
ThinkPHP的模板引擎扩展也是一个独立的类库实现,主要需要实现的方法包括:
```
/**
* 检测是否存在模板文件
* @access public
* @param string $template 模板文件或者模板规则
* @return bool
*/
abstract public function exists(string $template) : bool;
/**
* 渲染模板文件
* @access public
* @param string $template 模板文件
* @param array $data 模板变量
* @return void
*/
abstract public function fetch(string $template, array $data = []) : void;
/**
* 渲染模板内容
* @access public
* @param string $content 模板内容
* @param array $data 模板变量
* @return void
*/
abstract public function display(string $content, array $data = []) : void;
/**
* 配置模板引擎
* @access private
* @param string|array $name 参数名
* @param mixed $value 参数值
* @return void
*/
abstract public function config($name, $value = null);
```
具体实现可以参考[`think-twig`](https://github.com/yunwuxin/think-twig)扩展和[`think-blade`](https://github.com/terranc/think-blade)扩展。
### 命令行扩展
ThinkPHP命令行扩展主要是用于扩展命令行的指令,这种方式的扩展可以和某个独立类库同时存在,提供某项功能的命令行指令配合。官方的[队列扩展](https://github.com/top-think/think-queue)和[`Swoole`](https://github.com/top-think/think-swoole)扩展等都属于这个范畴,也是用途最广泛的扩展形式。
命令行扩展的指令注册可以使用下面的方式:
```
// 注册命令行指令
\think\Console::addDefaultCommands([
// 指令名 => 对应的命令类
'swoole' => '\\think\\swoole\\command\\Swoole',
'swoole:server' => '\\think\\swoole\\command\\Server',
]);
```
命令类必须继承系统的`think\console\Command`类,可以参考[掌握命令行的表格输出](https://blog.thinkphp.cn/754434)一文中的描述来完成命令行指令的实现。
### 分页显示驱动
ThinkPHP的分页默认使用的是`Bootstrap`驱动,你也可以自己扩展一个其它的驱动,以满足不同的分页显示需求。
分页驱动必须继承系统的`think\Paginator`类,具体可以参考内置的`think\paginator\driver\Bootstrap`类的实现。
### 行为扩展
ThinkPHP的行为类可以不需要继承任何的类库,只需要实现一个`run`方法
~~~
public function run($params);
~~~
如果需要使用额外的参数,可以使用依赖注入,具体可以参考官方手册的[钩子和行为](https://www.kancloud.cn/manual/thinkphp5_1/354129)章节内容。
### 中间件
ThinkPHP5.1高版本支持中间件,所以你可以通过中间件的方式来扩展功能。
中间件无需继承任何的类,只需要实现一个`handle`方法,
~~~
public function handle($request, \Closure $next)
~~~
具体可以参考官方手册的[中间件](https://www.kancloud.cn/manual/thinkphp5_1/564279)章节内容。
### `Response`扩展
系统内置的`Response`不一定满足所有的需求,你完全可以扩展一个`Response`类来实现特殊的需求。
`Response`扩展必须继承系统的`think\Response`类,并且必须实现`output`方法。
```
/**
* 处理数据
* @access protected
* @param mixed $data 要处理的数据
* @return mixed
*/
protected function output($data)
```
## 关于配置文件
如果你的ThinkPHP扩展(通常是专属扩展)需要使用独立的配置文件,你可以在扩展中自带一个默认配置,并且在安装扩展的同时复制到框架的配置目录下。
实现方式是修改你的`composer.json`文件,添加如下定义项:
```
// type必须指定为think-extend
"type": "think-extend",
"extra": {
"think-config": {
// 配置文件名 : 默认的配置文件
"swoole": "src/config/swoole.php",
}
}
```
## 官方推荐
由于`Composer`类库包太多,如果你认为自己的扩展很优秀,希望吸引更多用户使用,只要能够保持自主维护更新,可以把扩展提交给官方,由官方来推荐给开发者。
目前已经整理的推荐扩展可以参考:[ThinkPHP5相关资源汇总](https://blog.thinkphp.cn/913360)的第三方扩展推荐,每期的开发者周刊中也会推荐一些好用的扩展。
>[danger]### 你可以在本文最后的评论里面,提交自己开发的`Composer`类库或者扩展包地址,我们会陆续在开发者周刊中进行推荐(如果同时有相关的使用教程投稿最佳)。同时我们会在今年选择合适的时间进行一次扩展评选活动,敬请期待!
- 值得升级到5.1的18个理由
- 5.1.7版本新特性
- JSON字段类型在ORM中的使用
- 文件下载响应对象
- 教你使用5.1的数组对象查询
- 模型三大利器之一:搜索器
- 在ThinkPHP中使用Yaconf
- 掌握命令行的表格输出
- 5.1.25查询参数绑定的改进
- ThinkPHP安全规范指引
- 巧用数据集的排序功能实现统计排序
- think-orm ——基于5.1的独立ORM库
- think-template——基于ThinkPHP的独立模板引擎
- ThinkPHP5.1.26版本发布——修正版本,包含安全更新
- ThinkPHP5.0和3.2再发安全更新
- 官宣:ThinkPHP发布首个LTS版本
- 你真的了解Db类和模型的正确使用姿势么?
- 如何更有效的记录和管理日志
- 模型三大利器之二:修改器
- ThinkPHP5.1.28版本发布——修正上一版本问题,改进关联查询
- 模型三大利器之三:获取器
- API版本控制的几种思路
- ThinkPHP5.2第一个Beta版本发布测试
- 让你少犯错的数据查询基本原则
- ThinkPHP发布5.1.29版本——常规更新
- 这15个好习惯让你更容易升级到5.2
- 如何有效提高ThinkPHP的应用性能
- 让你提高开发效率的查询技巧
- 模型关联查询不完全指南
- 5.2发布Beta2版本——统一和精简大量用法
- ThinkPHP发布5.1.30版本——支持微秒时间字段写入
- ThinkPHP的数据缓存使用
- ThinkPHP5.2安装及入口文件
- ThinkPHP荣获2018 年度最受欢迎中国开源开发框架第1名
- 5.1路由使用心得技巧
- ThinkPHP5.*版本发布安全更新
- ThinkPHP项目及代码规范指北
- 5.2版本的设计规范指导
- ThinkPHP5.1.32版本发布——圣诞快乐
- 利用Trait特性给模型增加乐观锁功能
- 5.2数据库和模型的变化(摘要)
- ThinkPHP模板引擎实现和常见问题
- ThinkPHP5.0.24版本发布——安全更新
- 不忘初心,方得始终——ThinkPHP十三周年报告
- ThinkPHP5+相关资源汇总
- 异步社区ThinkPHP周年庆专享优惠活动
- 5.2路由的调整和改进
- ThinkPHP发布5.1.33版本——包含安全更新
- ThinkPHP扩展开发指南
- ThinkPHP发布5.2Beta3版本
- ThinkPHP发布5.1.34版本——喜迎新年
- ThinkPHP发布5.2RC1版本
- ThinkPHP发布5.1.35版本——常规更新
- 5.2配置类的调整
- 5.2时间查询的改进和优化
- 5.2RC版本升级不完全指导(仅供学习参考)
- ThinkPHP5.2版本正式变更为6.0版本
- ThinkPHP百度云云虚拟主机专享免费活动
- 事件系统以及查询事件、模型事件的使用
- ThinkPHP6.0RC2版本发布——架构升级、精简核心
- ThinkPHP5.1.36LTS版本发布——常规更新
- 新版Session和Cookie设计变化
- ThinkPHP5.1.37版本发布——常规更新
- ThinkPHP6.0RC3版本发布——细节完善,体验优化
- 6.0中间件使用详解
- Composer各大厂商镜像地址
- ThinkPHP6.0发布计划公告
- 「ThinkPHP开发者周刊」招募志愿者
- ThinkPHP6.0日志变化
- ThinkPHP5.1.38版本发布——常规更新
- ThinkPHP6.0RC4版本发布——ORM独立,日志多通道支持
- ThinkORM2.0开发指南上线
- ThinkPHP6.0RC5版本发布——多应用模式独立,中间件机制调整
- ThinkPHP6.0版本发布——程序员节福利
- ThinkPHP5.1.39LTS版本发布——常规更新
- ThinkPHP6.0.1版本发布——圣诞快乐!
- 回顾2019,展望2020!
- ThinkPHPV6.0.2版本发布——2020新春快乐!
- 周年福利系列:Swoole合作优惠
- 亿速云成为ThinkPHPV6.0独家赞助发布商🎉
- 新冠疫情工具和限免资源专题(保持更新中)
- 周年福利系列:创宇信用认证合作优惠
- 周年福利系列:码云企业版限时10%优惠
- 周年福利系列:想天短说抵现优惠
- think-swoole直播:从零开始掌握swoole开发
- 周年福利系列:B2C开源电商ShopXO授权8折优惠
- 周年福利系列:LayuiAdmin 永久授权限时优惠
- ThinkPHP资源导航站上线——构建生态 服务未来
- ThinkPHP官方技术支持服务和应用服务市场上线公测
- ThinkPHP市场精选——推广基本要素
- ThinkPHP市场精选——客服聊天专题
- ThinkPHPV6.0.3版本发布——端午安康
- ThinkPHP开发者扶持计划
- 6.0.3版本关键更新及升级事项
- 「ThinkPHP开发者周刊」改版重启
- ThinkPHP市场精选——企业建站专题
- ThinkPHP 提供统一API接口服务
- ThinkPHP市场精选——直播电商专题
- ThinkAPI服务SDK发布
- 官方服务市场启用独立子域名
- ThinkPHP市场精选——刷脸支付专题
- ThinkAPI推出会员服务计划
- ThinkPHPV6.0.4版本发布——中秋国庆双节快乐
- ThinkPHPV5.1.40版本发布——常规更新
- 1024程序员节福利走一波
- ThinkPHP V6.0.5版本发布——兼容Composer2.0
- 知识图谱应用场景——源论技术沙龙
- ThinkPHP5.*版本改进Composer2.0的兼容
- 官方市场双十一精选推荐
- 技术人做产品有机会么(文末送课程)
- 本周秒杀——古德云售后获客营销系统
- ThinkAPI服务更新——支持接口分组和PHP版本依赖调整
- PHP8新特性盘点
- PHP8新特性系列:构造器属性提升使用及注意事项
- ThinkPHP2021新年寄语
- ThinkPHP V6.0.6&V5.1.41版本发布——兼容PHP8.0
- PHP如何更优雅地调用API接口
- ThinkPHP V6.0.7发布——修正版本
- ThinkAPI服务更新——IP白名单
- 最新版ThinkORM对于时间字段的调整
- ThinkAPI短信接口正式上线
- ThinkPHP V6.0.8版本发布——多环境变量配置支持
- 顶想云写作服务开启第一次公测
- ThinkSSL上线——官方SSL/TLS证书服务
- MDBootstrap国内用户福利——ThinkPHP官方市场首发
- ThinkPHP V6.0.9版本发布——常规更新
- ThinkORM功能盘点——虚拟模型
- 全面支持主流GIT版本库——云写作服务第二次公测
- 云写作服务私有化部署方案之:版本库私有化
- 看云双十一活动
- ThinkPHP V6.0.10LTS发布——兼容PHP8.1
- ThinkPHP V6.0.12发布——命令行兼容8.1
- 顶想云知识管理上线公测——构建企业文档中心和知识库
- 顶想云上线——助力生态数字化建设
- 618活动进行中——官方市场迎来一波更新
- 顶想云知识管理正式上线——看云文档启动迁移服务
- ThinkPHP V6.0.13发布——常规更新
- 顶想云网站助理服务上线——构建产品支持服务
- ThinkPHP发布6.1.0&6.0.14版本——安全更新
- ThinkPHP新版社区上线试运营
- ThinkAPI上架人脸核身接口——助力网站实名认证
- 辞旧迎新——旧版社区停止注册及发帖
- ThinkPHP6.1.2版本发布——兼容PHP8.2