ThinkPHP5开发的正确姿势
安装篇
- 使用
composer
,既然是趋势就早日拥抱,能写PHP的这点工具用不来说不过去(另外官方的所有扩展都会以composer
方式提供); - 如果只需要核心单独安装核心框架就行了,应用仓库并非必须;
- 如果你安装的是
dev-master
,composer
更新的也是开发版,如果安装的是正式版那么更新的也是最新的正式版(就和Chrome的开发版和正式版一样); - 把web根目录指向
public
目录而不是根目录; - 资源文件不要放到
public
目录以外; - TP5完美支持PHP7,不要以为基于PHP7写的框架才会支持PHP7;
- 如果你的环境是PHP7,你的应用中完全可以使用PHP7的特性;
- 不要使用普通URL模式访问;
- TP5正常运行需要
PHP5.4+
,建议版本为PHP5.6+
; - 每次升级请务必参考官方手册提供的升级指导;
变量篇
- 避免直接获取系统变量,用
Request
对象的相关方法替代; - 不要管
get
还是post
请求,统一用param
方法获取当前请求(任何请求类型)变量; - 不要直接操作改变当前请求的系统变量;
- 使用操作方法的参数绑定功能,而不是自己手动获取请求参数;
- 使用依赖注入(TP5的依赖注入非常的简单);
- 对于一些请求用到的公共属性可以使用
Request
属性注入; - 用Request类的
getInput
方法替代file_get_contents('php://input')
; - 模板中输出系统变量使用
{$Request.param.name}
的方式; - 多使用Request类的
only
和except
方法获取多个请求变量; - 不要直接操作
$_SESSION
变量; - 任何变量必须事先定义才能操作或者赋值给模板;
路由篇
- 用动态注册方法而不是路由配置;
- 不要在路由配置文件之外定义路由;
- 用
get
/post
/delete
/put
等路由注册方法明确指定请求类型; - 保证路由变量和操作方法的参数绑定命名一致(包括可选);
- 路由地址保持和实际的控制器名和方法名一致(包括大小写);
- 为每个路由变量明确指定变量规则;
- 用路由分组简化路由定义和公共参数;
- 尽可能使用强制路由并配合MISS路由;
- 优先考虑资源路由尤其是API开发的时候;
- 考虑在路由后置行为中进行统一的权限检测;
- 部署后记得执行路由缓存指令;
- 了解下路由的请求缓存对你会有帮助;
控制器篇
- 建议开启
controller_suffix
配置参数,并采用IndexController
命名控制器类; - 原则上控制器类不需要继承
think\Controller
; - 给你的控制器类继承一个公共的基类例如
Base
便于统一调整; - 需要的话在你的基础控制器类中引入
traits\controller\Jump
; - API开发尽量使用资源控制器(命令行php think create:controller 可以快速生成);
- 控制器类中避免写太多的业务逻辑,交由模型类完成;
- 尽量避免直接操作数据库类,而是在模型类中做好封装;
- 可能的话尽量在控制器层完成数据验证;
- 不要试图在初始化方法中调用
redirect
助手函数,而用$this->redirect
方法替代; - 始终在控制器方法中
return
而不是echo
以免影响请求缓存; - 用
json
、view
以及redirect
助手函数进行响应输出; - 用
abort
助手函数抛出HTTP异常; - 遵循驼峰法命名你的控制器类和文件名;
- 永远不要在操作方法中(事实上是任何代码中)使用
exit
;
数据库篇
- 千万不要用驼峰法命名数据表和字段;
- 如非必要避免直接操作Db类;
- 用Db类的
name
方法而不是table
方法; - 用视图查询
view
方法替代join
方法; - 查询操作尽可能的使用
field
方法,哪怕是field(true)
; - 如果要批量执行SQL语句使用
batchQuery
方法; - 用
value
方法获取单个记录的某个字段值; - 用
column
方法获多条记录的某个(或者某些)字段值; - 灵活使用
cache
方法进行查询缓存处理和删除(不仅是查询可以用cache
方法); - 使用
fetchSql
方法直接返回sql语句而不实际执行CURD; - 部署之后记得执行命令行的
php think optimize:schema
指令; strict
方法可以避免多余的数据字段抛出异常;- 关于日期和时间的查询不妨试试
whereTime
方法; - 数据库的大多数操作都是自动参数绑定的,一般情况下无需手动使用
bind
方法; insert
方法返回的是影响的记录数而不是主键;- 使用
insertGetId
方法插入数据并返回主键; delete(true)
可以无条件的删除数据;select
和find
方法支持闭包,但尽量不要和链式操作混用;- 需要查询大量数据并且分批处理的话使用
chunk
方法; - 对find方法使用主键查询并且cache(true)的话缓存是自动更新的;
模型篇(上)
- 不要以为模型性能比Db差,这点差别还不抵不过一条SQL查询,而带来的便利是可观的;
- 模型的好处千言万语抵不过两个字:对象(明白人都会懂);
- 模型类一般直接继承
think\Model
,如有必要也可以继承一个公共模型基类; - 如果你的模型类没有任何的数据库操作的话不需要继承任何类库;
- 模型类不需要使用类后缀
Model
(对应前面的控制器类后缀); - 模型的
save
方法既可以新增也可以更新(而且是自动识别); - 模型没有链式操作,所有链式操作都是调用的数据库类Db;
- 模型支持事件而数据库类的操作不支持事件;
- 统一在模型的
init
方法(静态方法)中注册模型事件; - 模型没有数据表前缀的概念只有对应数据表(完整表名)的概念;
- 每个模型对应一个数据库查询对象Query,彼此独立;
- 每个模型可以单独定义自己的数据库连接信息;
- 模型名不一定就是数据表名,而且可以单独定义数据表名称;
- 模型查询的数据返回永远都是当前模型对象实例(而不是数组,Db类查询才是数组);
- 模型对象可以直接进行数组操作并不需要使用
toArray
转换(包括模板输出);
模型篇(下)
- 模型的查询操作建议使用
get
和all
方法(静态方法); - 要在模型查询中使用链式查询可以定义查询范围或者使用闭包;
- 用
save
方法新增数据的返回值是影响的记录数而不是主键值,获取主键直接获取当前模型对象的属性值即可; - 如果仅仅是需要主键之外的查询条件的话,可以在
get
或者all
方法的第一个参数使用数组; - 要模型查询后的原始数据可以使用
getData
方法; - 模型的关联操作可以让你省去很多的关联查询;
- 鉴于性能考虑,关联预载入查询绝对是关联查询的首选;
- 软删除必须使用模型的
delete
方法(而不是数据库类的delete
)才有效; - 不要在修改器中修改多个属性;
- 修改器是模型才有的功能,调用数据库Db类的写入操作方法是不会触发的;
- 不要在同一个模型实例中多次调用
save
新增数据,一旦新增数据成功后,再次save就是更新数据了,除非你显式调用isUpdate(false)
; - 用模型事件取代自动完成;
其它篇
- 开发过程中开启调试模式,部署后记得关闭;
- 如果不是API开发的话开启页面Trace显示;
- 不要轻易忽视异常页面的任何信息,它们不是摆设;
- 开发中一定要严格注意大小写,这是基本素质;
- 如果是接口开发尝试使用
postman
进行调试; - 使用命名空间和自动加载,避免直接
require
及include
; - 不建议使用
import
和vendor
方法; - 应用目录下面的
common.php
(注意不是command.php
)可以添加应用的函数,并且实时生效; - 不要手动下载扩展包放入
vendor
目录,不支持composer安装的扩展类库直接放入extend
; - 只要是使用命名空间的第三方类库,都是可以直接在TP5下面使用的;
- 尽可能的采用
MVVM
设计架构来替代MVC
架构,充分发挥TP5的API优势; - 如果使用模板,避免在模板中使用过多的数据逻辑;
- 模板继承和模板布局是可以配合使用的;
版权声明:
作者:admin
链接:http://blog.mryxh.cn/1909.html
文章版权归作者所有,未经允许请勿转载。
THE END