You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用额外包的情况下将Laravel应用转为多租户应用

Laravel 无额外包实现单库多租户(SaaS化改造)

不少开发者都碰到过这种场景:给初创公司做完定制应用后,要把它改成面向SaaS的多租户产品。用Laravel的话,不用额外安装第三方包就能轻松完成这个过渡。下面就给大家展示针对标准API应用的单数据库方案,实现逻辑简洁直观。


核心实现步骤

  • 给业务表添加租户标识字段
    给用户、订单这类核心业务表新增tenant_id字段,类型与租户表主键匹配(比如unsignedBigInteger),同时建立外键关联到租户表:

    // 示例迁移代码
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedBigInteger('tenant_id')->after('id');
        $table->foreign('tenant_id')->references('id')->on('tenants')->onDelete('cascade');
    });
    
  • 实现租户识别中间件
    新建Tenant模型后,写一个全局中间件,从请求头(比如X-Tenant-ID)获取当前租户ID,验证合法性后给模型添加全局作用域,实现数据隔离:

    // 租户中间件示例
    public function handle(Request $request, Closure $next)
    {
        $tenantId = $request->header('X-Tenant-ID');
        
        if (!$tenantId) {
            return response()->json(['error' => '缺少租户ID'], 400);
        }
    
        if (!Tenant::find($tenantId)) {
            return response()->json(['error' => '无效租户ID'], 404);
        }
    
        // 为需要隔离的模型添加全局作用域
        collect([User::class, Order::class])->each(function ($model) use ($tenantId) {
            $model::addGlobalScope('tenant', fn($query) => $query->where('tenant_id', $tenantId));
        });
    
        return $next($request);
    }
    

    记得将该中间件注册到API路由组中,确保所有API请求都经过租户校验。

  • 封装租户作用域Trait
    把租户作用域逻辑封装成Trait,让需要多租户隔离的模型直接引用,减少重复代码:

    trait TenantScoped
    {
        protected static function booted()
        {
            static::addGlobalScope('tenant', function ($query) {
                $tenantId = request()->header('X-Tenant-ID');
                if ($tenantId) {
                    $query->where('tenant_id', $tenantId);
                }
            });
        }
    }
    
    // 在User模型中使用
    class User extends Model
    {
        use TenantScoped;
        // ... 其他模型逻辑
    }
    
  • 自动关联租户ID
    创建业务数据时,自动从请求头获取租户ID并赋值,避免手动操作出错:

    // 示例:创建用户时自动绑定租户
    $user = User::create([
        'name' => $request->input('name'),
        'email' => $request->input('email'),
        'password' => Hash::make($request->input('password')),
        'tenant_id' => request()->header('X-Tenant-ID'),
    ]);
    

这种单库方案架构简单,查询性能损耗低,适合中小规模的SaaS应用,不用引入复杂的多租户包就能快速完成应用的SaaS化改造。

内容的提问来源于stack exchange,提问作者Max Shaian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:35:12