ThinkPHP 8.0多应用架构落地:分离API与后台管理,告别单体臃肿

2026-06-24 0 375

项目初期我们习惯把API、后台、前端控制器全塞进同一个app目录里。业务量一起来,控制器和模型文件混在一起,路由定义挤在同一个文件里,想给API加个全局中间件还得小心翼翼避开后台的路由。更头疼的是团队分工——负责后台的同事和负责API的同事修改同一个app目录,代码合并时频繁冲突。

ThinkPHP 8.0多应用模式就是为了解决这种复杂度而生的。它允许在同一个项目下划分出多个独立的应用,每个应用有自己的控制器、模型、视图、路由和配置。这篇借着我们团队最近拆旧项目的经验,把多应用的搭建过程、路由策略、跨应用交互和部署细节完整写出来。

一、启用多应用模式

ThinkPHP 8.0默认是单应用模式,入口都在app目录下。要改成多应用,首先需要在项目根目录的composer.json中确认安装了多应用扩展:

composer require topthink/think-multi-app

安装完成后,框架会自动识别app目录下的子目录作为独立应用。一个典型的多应用目录结构:

project/
├── app/
│   ├── api/          # API应用
│   │   ├── controller/
│   │   ├── model/
│   │   ├── middleware/
│   │   ├── route/
│   │   │   └── app.php
│   │   └── common.php
│   ├── admin/        # 后台管理应用
│   │   ├── controller/
│   │   ├── model/
│   │   ├── view/
│   │   ├── middleware/
│   │   ├── route/
│   │   │   └── app.php
│   │   └── common.php
│   └── BaseController.php  # 公共基类
├── config/
├── public/
│   ├── index.php
│   └── admin.php     # 后台入口(可选)
├── route/
│   └── app.php       # 全局路由
└── extend/

每个应用有自己的目录结构,路由文件在各自route/app.php里定义,互不干扰。公共的基类、traits或者第三方库放在app根目录或extend中,供所有应用使用。

二、创建API应用

先建API应用。在app/api/下创建controller目录,写一个简单的用户列表接口:

<?php
namespace appapicontroller;

use appapicontrollerBase;
use thinkfacadeDb;

class User extends Base
{
    public function list()
    {
        $users = Db::table('users')->field('id, nickname, avatar, phone')->paginate(15);
        return json([
            'code' => 0,
            'data' => $users,
        ]);
    }
}

API应用需要一个基类来统一处理JSON响应和权限校验。在app/api/controller/Base.php中:

<?php
namespace appapicontroller;

use thinkfacadeApp;
use thinkexceptionHttpResponseException;
use thinkResponse;

class Base
{
    protected function jsonSuccess($data = [], string $msg = 'ok', int $code = 0)
    {
        $response = json([
            'code' => $code,
            'msg'  => $msg,
            'data' => $data,
        ]);
        throw new HttpResponseException($response);
    }

    protected function jsonError(string $msg = 'error', int $code = 1, int $httpCode = 200)
    {
        $response = json([
            'code' => $code,
            'msg'  => $msg,
        ], $httpCode);
        throw new HttpResponseException($response);
    }
}

接着定义路由。在app/api/route/app.php中:

<?php
use thinkfacadeRoute;

Route::group('v1', function () {
    Route::get('users', 'User/list');
});

外部访问的URL就是/api/v1/users。这里的路径自动匹配应用名,因为入口文件默认是public/index.php,框架根据URL中的第一个路径段api来定位到app/api应用,后面的v1/users交给该应用的路由处理。

三、创建后台管理应用

后台应用通常需要视图渲染、表单提交和权限管理。在app/admin/下创建controller/Index.php

<?php
namespace appadmincontroller;

use thinkfacadeView;

class Index
{
    public function dashboard()
    {
        // 渲染后台首页视图
        return View::fetch();
    }
}

后台的路由在app/admin/route/app.php

<?php
use thinkfacadeRoute;

Route::get('dashboard', 'Index/dashboard');

后台的入口URL就是/admin/dashboard。如果你想为后台设置独立域名或二级域名,可以在入口文件public/index.php里做域名绑定,或者用Nginx转发。但多应用模式本身就支持按应用名访问,不搞独立域名也能很好工作。

四、中间件的隔离

不同应用通常需要不同的中间件。比如API需要JWT认证或限流,后台需要登录态检测和权限验证。中间件可以定义在各自应用的middleware目录下,然后在应用的路由文件或控制器中单独使用。

以API的简单Token校验为例,创建app/api/middleware/Auth.php

<?php
namespace appapimiddleware;

use thinkResponse;

class Auth
{
    public function handle($request, Closure $next)
    {
        $token = $request->header('Authorization');
        if (!$token || !$this->validateToken($token)) {
            return Response::create([
                'code' => 401,
                'msg'  => '未授权',
            ], 'json', 401);
        }
        return $next($request);
    }

    private function validateToken(string $token): bool
    {
        // 具体校验逻辑
        return true;
    }
}

在API的路由文件app/api/route/app.php中应用这个中间件:

Route::group('v1', function () {
    Route::get('users', 'User/list');
})->middleware(appapimiddlewareAuth::class);

后台应用也有自己的中间件,两者完全隔离,不会互相干扰。

五、模型层和公共代码共享

API和后台都操作同一套数据库表,如果两个应用各自写一份模型,字段定义和业务逻辑就会重复。共享模型有两种方式:一是把模型放在app/model公共目录(单应用模式的位置),二是在app下建一个common目录放置公共模型。ThinkPHP在多应用模式下可以自动加载app/model下的类,所以最简单的方法是把模型放在那里。

例如app/model/User.php

<?php
namespace appmodel;

use thinkModel;

class User extends Model
{
    protected $table = 'users';
    protected $pk = 'id';
}

在API和后台控制器里都可以直接use appmodelUser;使用,保证了数据层的一致性和复用。

如果需要跨应用调用服务层(如API需要用到后台的某个统计Service),则建议把服务类放在app/common/service中,或者通过依赖注入解耦。

六、配置的继承与覆盖

每个应用可以有自己独立的配置文件,放在应用目录下的config文件夹里。比如API需要不同的数据库连接或者不同的缓存前缀,就可以在app/api/config/database.php中覆盖全局配置。

应用配置的优先级:应用自己的配置 > 全局config目录下的配置。这种分层设计让全局设置和个性化分离得很好,不需要为了一个应用的特殊需求改动全局配置。

七、跨应用调用与RPC

尽管各应用独立,但有时候API应用需要调用后台应用的一个功能,例如推送统计通知。在多应用模式下,最佳实践是避免直接引用对方的控制器或类——那样会产生耦合。替代方案包括:

  • 把公共业务逻辑抽到app/common目录中,两个应用都调用它。
  • 使用内部RPC(在同一个进程内直接调用公共Service层)。
  • 如果部署在不同的服务器或容器,采用HTTP接口互相调用,并加上签名验证。

对于同机部署的情况,抽公共Service是最快的办法:

// app/common/service/StatisticsService.php
namespace appcommonservice;

use appmodelUser;

class StatisticsService
{
    public function getUserCount(): int
    {
        return User::count();
    }
}

然后在任何应用中调用:

$count = app('appcommonserviceStatisticsService')->getUserCount();

八、入口文件与域名绑定

生产环境可能需要将api.example.com指向API应用,admin.example.com指向后台。ThinkPHP的多应用模式可以通过在入口文件设置app_name来实现。例如为API设置独立入口文件public/api.php

// public/api.php
namespace think;

// 设置应用名称
define('APP_NAME', 'api');

require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/topthink/framework/src/helper.php';

(new App())->http->run();

然后在Nginx中把api.example.com转发到public/api.php。这样无论是路径还是域名,都能灵活地指向不同应用。

九、迁移旧单应用项目的一点经验

我们把旧项目从单应用迁移到多应用时,采取了分步走的方式:

  1. 先启用topthink/think-multi-app,框架会自动识别app下的子目录。此时老控制器仍可以留在原地,不会报错。
  2. 新建app/apiapp/admin目录,逐步移动对应模块的控制器和路由。
  3. 将共用的模型和服务抽到app/modelapp/common
  4. 配置各自的中间件和路由分组,最后上线切换域名或路径。

整个迁移过程花了两天,测试完之后,代码结构清晰了很多,团队协作的冲突也明显减少了。

十、总结

ThinkPHP 8.0的多应用模式不是新瓶装旧酒,它是项目规模增长后的自然选择。一个项目拆成两个甚至更多的应用,不仅让目录树一目了然,也让中间件、路由和配置的管理变得有条理。复用公共的模型和服务,既避免了重复劳动,又保持了数据层的统一。

如果你现在维护的ThinkPHP项目开始觉得app目录里东西越来越多、越来越乱,不妨考虑用多应用模式拆分一下。可以先从最独立的模块开始(比如API),建一个新应用,移一波控制器,跑通路由,再逐步迁移其他模块。这个投入产出的改善,大概率会让你觉得值得。

ThinkPHP 8.0多应用架构落地:分离API与后台管理,告别单体臃肿
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

版权声明:
本站资源有的来自互联网收集整理,本站纯免费分享提供学习使用,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站资源仅供研究、学习交流之用,免费开源项目不代表完全可商用,若商业用途请先咨询开发企业能否商用,否则产生的一切后果将由下载用户自行承担。
原创板块未经允许不得转载,否则将追究法律责任。

淘吗网 thinkphp ThinkPHP 8.0多应用架构落地:分离API与后台管理,告别单体臃肿 https://www.taomawang.com/server/thinkphp/2275.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务