如何在不使用额外包的情况下将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
相关产品推荐
相关产品推荐

