thinkphp函数封装需按问题类型分层处理:验证逻辑用trait、工具函数放function.php、业务逻辑下沉service层、数据库连接靠配置一致性、模板复用靠路径规范。

ThinkPHP函数封装不是堆砌代码,而是按问题类型选对位置、定好边界、留出扩展点。核心在于:验证逻辑用 Trait、公共工具放 function.php、业务逻辑沉到 Service 层、数据库连接靠配置一致性、模板复用靠路径规范。
验证逻辑统一用 Trait 封装
别在每个控制器里重复写 $this->validate($data, UserValidate::class)。规则散落、scene 不生效、报错难定位,本质是验证行为没抽离。
- 新建
app\common\trait\ValidatesForm.php,只定义一个validateForm()方法,接收$data、$validatorClass和可选$scene - 内部必须用
new $validatorClass()实例化验证器,再调check(),否则$scene无效 - 验证类中用
protected $scene = ['register' => ['mobile', 'email']]控制字段,不建多个类 - 控制器里统一调
$this->validateForm($data, UserValidate::class, 'register')
通用工具函数集中放在 function.php
像 CURL 请求、输入过滤、日志记录这类无状态、跨模块使用的逻辑,适合封装成普通函数,自动加载即可全局调用。
- 在
app\common\common\function.php(全项目可用)或app\home\common\function.php(仅前台)创建文件 - 例如封装安全输入过滤:
function sanitizeInput($input) { return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8'); } - 在
app\common\conf\config.php中配置'LOAD_EXT_FILE' => 'function',框架启动时自动引入 - 避免在控制器里反复写 curl_init() —— 写一次, anywhere 都能
curl('https://api.example.com')
业务逻辑必须下沉到 Service 层
控制器里塞满 DB 查询、条件判断、数组组装,是复用率低的根源。Service 层要无 HTTP 上下文、无 Request/Response 依赖、支持 DI 注入。
- 新建
app\common\service\UserService.php,构造方法接收UserModel或Db实例,而非硬编码 new - 方法只做一件事:如
createUser(array $data)负责校验+写库+发通知,不 echo、不 redirect、不 assign - 控制器里只写
$user = $this->userService->createUser($postData),职责清晰,单元测试也容易写 - 后续换数据库、加事务、接消息队列,改 Service 即可,控制器零改动
数据库连接复用靠配置一致,不是靠开关
'persistent' => true 不等于连接池。连接是否复用,取决于运行时连接参数是否「完全一致」:键名顺序、值类型('port' => 3306 和 'port' => '3306' 视为两个连接)、是否显式传参。
- 禁用手动
Db::connect([...]),改用预设连接名,如Db::name('user')->connection('mysql') - 检查模型里
protected $connection = 'mysql2'是否对应 config/database.php 中真实定义的连接名,否则 TP fallback 新建连接 - Swoole 协程环境下必须装
think-swoole扩展,并设置'auto_close' => false,手动归还连接,否则协程退出前连接就断了 - 调试时监听
Connect事件,比翻配置文件更准——记录每次连接的堆栈和时间戳,一眼看出哪段代码触发了新连
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











