튜토리얼 칼럼에서 Laravel의 애플리케이션에 다중 테넌트 기능을 몇 분 안에 제공하기 위해 소개한 내용입니다. 필요한 친구들에게 도움이 되길 바랍니다!
이 튜토리얼에서는Tenancy for Laravel 패키지를 사용하여 Laravel 애플리케이션을 다중 테넌트로 만듭니다.
추가 코드를 다시 작성할 필요 없이 Laravel 애플리케이션이 다중 테넌트가 될 수 있도록 하는 다중 테넌트 소프트웨어 패키지입니다
. 렌탈 패키지만큼 플러그 앤 플레이 방식입니다.
참고: 이 튜토리얼에서는 가장 일반적인 설정인 여러 도메인의 다중 데이터베이스 테넌시를 다룹니다. 다른 설정이 필요한 경우 100% 가능합니다. 패키지를 확인해 보세요.
작동 방식이 패키지의 독특한 점은 애플리케이션을 특정 방식으로 작성하도록 강요하지 않는다는 것입니다. 익숙한 대로 애플리케이션을 작성할 수 있으며 내부적으로 다중 테넌시가 자동으로 생성됩니다. 패키지를 기존 애플리케이션에 통합할 수도 있습니다.
1. 서버가 사용자 요청을 받으면
2. 프로그램은 요청을 통해 해당 요청이 어느 테넌트에 속하는지 식별할 수 있습니다. (기본 도메인 이름, 하위 도메인 이름, 경로, 요청 헤더, 쿼리 매개변수 등을 통해)3. 프로그램은
default 데이터베이스 링크에서 현재 테넌트 링크로 전환됩니다.
4. 모든 데이터베이스 호출, 캐시 호출, 대기열 호출 및 기타 작업은 자동으로 테넌트 및 스위치와 일치합니다.
Installation
첫 번째 단계는 작곡가를 통해 패키지를 설치하는 것입니다. 명령은 다음과 같습니다.
composer require stancl/tenancy
tenancy:install
명령을 다음과 같이 실행합니다. php artisan tenancy:install
이 작업은 다음을 생성합니다. 다음 파일: 마이그레이션 파일, 구성 파일, 라우팅 파일 및 서비스 공급자.
다음 명령을 통해 데이터베이스를 설정하고 데이터베이스 마이그레이션을 수행해 보겠습니다. tenancy:install
命令,如下:
php artisan migrate
该操作会产生以下文件:迁移文件,配置文件,路由文件和一个服务提供者。
下面让我们把数据库建立起来,通过以下命令执行数据库迁移:
/* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, App\Providers\TenancyServiceProvider::class, // <-- 放于此处
然后在 config/app.php
注册服务提供者。请确定将代码放于以下位置:
<?php namespace App; use Stancl\Tenancy\Database\Models\Tenant as BaseTenant; use Stancl\Tenancy\Contracts\TenantWithDatabase; use Stancl\Tenancy\Database\Concerns\HasDatabase; use Stancl\Tenancy\Database\Concerns\HasDomains; class Tenant extends BaseTenant implements TenantWithDatabase { use HasDatabase, HasDomains; }
现在,我们创建一个自定义的 tenant 模型。该程序包是不受限制的,因此要使用单独的数据库和域,我们需要创建一个略微定制的 tenant 模型。使用以下代码创建一个 app/Tenant.php
文件:
// config/tenancy.php file 'tenant_model' => \App\Tenant::class,
现在,我们告诉程序包将该模型用于 tenants:
protected function mapWebRoutes() { foreach ($this->centralDomains() as $domain) { Route::middleware('web') ->domain($domain) ->namespace($this->namespace) ->group(base_path('routes/web.php')); } } protected function mapApiRoutes() { foreach ($this->centralDomains() as $domain) { Route::prefix('api') ->domain($domain) ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); } } protected function centralDomains(): array { return config('tenancy.central_domains'); }
软件包将您的应用程序视为两个独立的部分:
了解了这两个部分,让我们将应用进行相应的拆分。
首先让我们确保 central 应用仅在中心域上可访问。
转到 app/Providers/RouteServiceProvider.php
,并确保您的 web
和 api
路由仅在中央域上加载:
'central_domains' => [ 'saas.test', // Add the ones that you use. I use this one with Laravel Valet. ],
现在转到您的文件 config/tenancy.php
,实际添加中心域。
我使用的是 Valet,所以对我来说,中心域是 saas.test
,租户域以 foo.saas.test
和bar.saas.test
为例。
因此,我们设置 central_domains
键:
Route::middleware([ 'web', InitializeTenancyByDomain::class, PreventAccessFromCentralDomains::class, ])->group(function () { Route::get('/', function () { return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id'); }); });
现在是有趣的部分。这一部分几乎太简单了。
要使某些代码具有租户意识,您只需执行以下操作:
tenant/
目录tenant.php
路由文件就是这样。
在该特定文件夹中进行迁移并且在该特定路由文件中包含路由将通知包标识该路由上的租户。
如果您有现有的应用程序,请使用您的代码执行此操作。如果您使用的是全新应用,请按照以下示例操作:
默认情况下,您的租户路由如下所示:
Route::get('/', function () { dd(\App\User::all()); return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id'); });
这些路由只能在 tenant (非中心) 域上访问 —— PreventAccessFromCentralDomains
中间件会强制执行这一点。
让我们做一点小更改以转储数据库中的所有用户,以便我们可以实际看到多租户工作。将此添加到中间件组:
>> $tenant1 = Tenant::create(['id' => 'foo']); >> $tenant1->domains()->create(['domain' => 'foo.saas.test']); >>> >> $tenant2 = Tenant::create(['id' => 'bar']); >> $tenant2->domains()->create(['domain' => 'bar.saas.test']);
现在,迁移。只需将与租户应用程序相关的迁移移动到database/migrations/tenant
App\Tenant::all()->runForEach(function () { factory(App\User::class)->create(); });
config/app.php
에 서비스 공급자를 등록합니다. 다음 위치에 코드를 배치해야 합니다. 🎜rrreee🎜이제 사용자 지정 테넌트 모델을 만들어 보겠습니다. 패키지는 연결되어 있지 않으므로 별도의 데이터베이스와 도메인을 사용하려면 약간 사용자 지정된 테넌트 모델을 만들어야 합니다. 다음 코드를 사용하여 app/Tenant.php
파일을 만듭니다. 🎜rrreee🎜이제 테넌트에 대해 이 모델을 사용하도록 패키지에 지시합니다. 🎜rrreee🎜두 부분🎜🎜패키지는 앱을 다음과 같이 사용합니다. 두 개의 개별 부분: 🎜app/Providers/RouteServiceProvider.php
로 이동하여 web
및 api
경로가 중앙 도메인에만 로드되는지 확인하세요: 🎜rrreee 🎜이제 config/tenancy.php
파일로 이동하여 실제로 중앙 도메인을 추가하세요. 🎜🎜저는 Valet을 사용하고 있으므로 중앙 도메인은 saas.test
이고 테넌트 도메인은 foo.saas.test
및 bar.saas입니다. 예를 들어 테스트
. 🎜🎜그래서 central_domains
키를 설정했습니다. 🎜rrreeetenant/
디렉터리로 이동 PreventAccessFromCentralDomains 미들웨어가 이를 시행합니다. 🎜🎜실제로 다중 테넌시가 작동하는 것을 볼 수 있도록 데이터베이스의 모든 사용자를 덤프하도록 약간 변경해 보겠습니다. 미들웨어 그룹에 다음을 추가하세요: 🎜rrreee🎜이제 마이그레이션하세요. 테넌트 애플리케이션과 관련된 마이그레이션을 <code>database/migrations/tenant
디렉터리로 이동하기만 하면 됩니다. 🎜因此,对于我们的示例:要使用户进入租户数据库,让我们将users表迁移移至数据库/迁移/租户。这将防止在中央数据库中创建表,而是在创建租户时在租户数据库中创建表。
现在让我们创建一些租户。
我们还没有可供租户注册的登录页面,但是我们可以在修补程序中创建他们!
因此,让我们打开php artisan tinker
并创建一些租户。租户实际上只是模型,因此您可以像其他任何Eloquent模型一样创建它们。
请注意,我们在 这里使用域标识因此,请确保您使用的域指向您的应用程序。我正在使用代客,所以我正在*.saas.test
用于租户。如果使用php artisan serve
,则可以使用foo.localhost
。
>> $tenant1 = Tenant::create(['id' => 'foo']); >> $tenant1->domains()->create(['domain' => 'foo.saas.test']); >>> >> $tenant2 = Tenant::create(['id' => 'bar']); >> $tenant2->domains()->create(['domain' => 'bar.saas.test']);
现在,我们将在每个租户的数据库中创建一个用户:
App\Tenant::all()->runForEach(function () { factory(App\User::class)->create(); });
就是这样- 我们有一个多租户应用程序!
如果您访问 foo.saas.test
(或与您的环境相当),则会看到用户转储。
如果访问bar.saas.test
,您将看到不同用户的转储 。数据库是100%分离的,我们使用的代码 —App\User::all()
— 根本不需要了解租约!这一切都会在后台自动发生。您只需像以前那样编写应用程序,而不必考虑自己的范围界定,并且一切都正常。
当然,现在,租户应用程序中将有一个更复杂的应用程序。仅转储用户的SaaS可能用处不大。这就是您的工作-编写将由租户使用的业务逻辑。包装将处理其余部分。
不过,Tenancy for Laravel 项目的帮助并没有到此结束。该软件包将为您完成与多租户相关的所有繁重工作。但是,如果您要构建SaaS,则仍然需要自己编写计费逻辑,入门流程和类似的标准内容。如果您有兴趣,该项目还提供了一个优质产品:multi-tenant SaaS boilerplate。它旨在通过为您提供通常需要编写的SaaS功能来节省您的时间。所有这些都打包在一个随时可以部署的多租户应用程序中。
原文地址:https://laravel-news.com/multi-tenant
译文地址:https://learnku.com/laravel/t/47951
위 내용은 몇 분 안에 Laravel 애플리케이션을 다중 테넌트로 만드는 방법을 가르쳐주세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!