直接用PHP写一个小页面并不困难:接收参数、查询数据库,再把结果输出到浏览器就能运行。但当项目逐渐增加登录、权限、商品、订单、接口、缓存和日志以后,如果所有代码都混在几个PHP文件里,维护很快就会变得麻烦。
ThinkPHP解决的就是这类问题。它不是一个安装之后就能直接发布文章的CMS,也不是某套固定的网站模板,而是一套PHP Web开发框架。开发者仍然需要编写自己的业务代码,只不过路由、请求处理、数据库操作、配置管理等通用工作已经有了一套相对完整的组织方式。

ThinkPHP到底是什么
ThinkPHP是一个开源PHP框架,当前主要版本为ThinkPHP 8系列。官方项目说明中,ThinkPHP 8基于PHP 8.0及以上环境构建,并使用Composer管理相关依赖。
如果把一个网站拆开来看,请求进入服务器以后通常要经历很多步骤:
用户访问URL ↓ 路由判断请求交给谁 ↓ 控制器接收请求 ↓ 执行业务逻辑 ↓ 查询或写入数据库 ↓ 返回HTML或JSON
不用框架时,这些事情也可以自己实现;使用ThinkPHP以后,则可以按照框架已有的规则组织代码。开发人员主要把精力放在“订单怎么处理”“用户怎么登录”这类业务问题上,而不用每个项目都重新设计一遍基础结构。
先看懂ThinkPHP的项目目录
通过Composer创建一个ThinkPHP项目以后,会看到一些比较固定的目录。理解这些目录,比一开始记大量函数更有用。
| 目录 | 主要用途 |
|---|---|
| app | 应用业务代码,例如控制器、模型等 |
| config | 应用配置 |
| route | 路由定义 |
| public | 网站公开入口及静态资源 |
| runtime | 运行过程中生成的缓存、日志等数据 |
| vendor | Composer安装的框架及第三方依赖 |
这种结构带来的好处不是“文件看起来整齐”,而是不同职责有了相对明确的位置。接手别人项目时,至少知道路由应该去哪里找,业务控制器大致在哪里,配置也不需要散落在代码各处。
路由决定一个URL由谁处理
ThinkPHP中的路由,可以理解成URL和程序处理逻辑之间的映射。
例如希望访问:
/article/100
时读取编号为100的文章,可以为它定义对应路由,再交给文章控制器处理。
这样做以后,对外展示的URL和内部PHP文件不需要形成简单的一一对应关系。开发REST API时,也可以根据GET、POST等不同请求方式设置不同处理逻辑。
路由的价值在项目变大以后会更明显。商品、用户、订单和文章拥有各自的URL规则,比在一个入口文件中不断判断参数更容易维护。
控制器负责接住请求
路由确定目标以后,请求通常会进入控制器。控制器更像业务流程的入口:接收参数,调用需要的业务或数据逻辑,然后决定返回什么。
例如一个简单方法可能是:
public function hello($name = 'ThinkPHP')
{
return 'Hello ' . $name;
}实际项目当然不会这么简单。一个订单接口可能需要先检查登录状态,再验证提交参数,查询商品库存,创建订单,最后返回JSON。
需要注意的是,控制器并不适合塞进所有业务代码。项目稍微复杂一些以后,通常还会把数据库模型、服务逻辑和验证规则继续拆开,否则只是从“所有代码写在一个PHP文件”变成“所有代码写在一个控制器”。
数据库和ORM是ThinkPHP常用的一部分
Web项目很难绕过数据库。ThinkPHP生态中的ThinkORM负责数据库与ORM相关能力,可以通过查询构造器或模型完成常见的数据操作。
例如查询一个用户,可以写成类似:
$user = Db::name('user')
->where('id', 100)
->find();相比自己拼接SQL,这种写法在大量常规增删改查场景中更容易统一代码风格。
进一步使用模型以后,还可以把用户、文章、订单等业务实体单独组织起来,处理字段转换、关联关系和数据操作。
不过ORM也不是要求开发者从此完全不懂SQL。遇到复杂查询、索引设计、慢查询和大数据量处理时,数据库本身的知识仍然非常重要。框架减少的是重复代码,而不是替代数据库能力。
中间件适合处理重复的请求逻辑
很多网站都有一些几乎每个接口都需要做的事情,例如检查用户是否登录、记录请求日志、判断接口访问频率或者统一增加响应信息。
如果在每个控制器里都写一遍,不但重复,而且以后修改规则时容易漏掉。ThinkPHP提供中间件机制,可以在请求正式进入业务逻辑前后统一处理这些事情。
例如后台管理系统可以让一组路由统一经过身份认证中间件。认证失败直接返回登录提示,通过以后才进入具体控制器。
这类机制也是使用框架和“几个PHP文件直接写到底”之间比较明显的区别。框架真正提供的是一套组织大型代码的办法。
不只有传统MVC网站
早期接触ThinkPHP的人,经常会把它和MVC联系在一起:Model负责数据,View负责页面,Controller负责请求。
这个理解没有问题,但现在使用ThinkPHP并不意味着一定要采用传统的服务端模板网站。
例如Vue、React或者小程序负责前端界面,ThinkPHP只提供JSON API,这时项目可能几乎不使用传统View层。后台管理系统、移动端接口、企业内部系统和前后端分离项目,都可以使用同一套框架基础能力。
所以ThinkPHP更准确的理解应该是PHP后端开发框架,而不是“用来套HTML模板的工具”。
为什么不少国内PHP项目选择它
ThinkPHP的一个现实特点,是中文资料和国内开发生态比较成熟。很多CMS、商城、后台系统以及企业项目曾经或者仍然建立在ThinkPHP之上,因此国内PHP开发人员接手已有项目时,经常会碰到它。
框架本身也提供了Web项目中经常需要的路由、中间件、请求与响应、配置、日志、缓存、验证以及数据库相关基础设施,不需要为了每个常见需求重新选择一套完全不同的实现。
当前ThinkPHP 8要求PHP 8.0及以上版本,官方后续8.1.x更新还在继续改进路由、请求响应以及ORM,并增加了对较新PHP版本的兼容。
对于已经熟悉PHP语法,又希望从零散PHP脚本进入结构化项目开发的人,ThinkPHP的学习路线也比较直观:先学路由和控制器,再理解请求、数据库、模型、中间件和验证,基本就能够开始完成普通业务系统。
poxiaoxi博客
精彩评论