下面由laravel教程欄目給大家介紹在幾分鐘內(nèi)使Laravel應(yīng)用擁有多租戶功能的方法,希望對需要的朋友有所幫助!
在本教程中,我們將使用?Laravel讓Laravel 應(yīng)用實現(xiàn)多租戶。
它是一個多租戶軟件包,讓你的laravel應(yīng)用程序?qū)崿F(xiàn)多租戶?不需要復(fù)寫額外代碼。 它就像租賃包一樣即插即用。
旁注:在本教程中,我們將介紹最常見的設(shè)置-多個域上的多數(shù)據(jù)庫租賃。如果你需要一個不同的設(shè)置,這是100%可能的。只需查看文件包。
工作原理
這個包的獨特之處在于它不會強迫您以特定的方式編寫應(yīng)用程序。你可以像你習(xí)慣的那樣編寫你的應(yīng)用程序,它會在后臺自動生成多租戶。您甚至可以將包集成到現(xiàn)有的應(yīng)用程序中。
以下是它的工作原理:
1.當(dāng)服務(wù)器接收到用戶請求
2.程序便可以通過請求識別該請求屬于哪個租戶。(通過主域名,子域名,路徑,請求頭,query 參數(shù),等)
3.程序?qū)?default?數(shù)據(jù)庫鏈接切換為當(dāng)前租戶鏈接。
4.任意的數(shù)據(jù)庫調(diào)用,緩存調(diào)用,隊列調(diào)用,等操作都會自動匹配租戶并切換。
安裝
第一步,通過 composer 安裝 package,命令如下:
composer require stancl/tenancy
然后,執(zhí)行?tenancy:install 命令,如下:
php artisan tenancy:install
該操作會產(chǎn)生以下文件:遷移文件,配置文件,路由文件和一個服務(wù)提供者。
下面讓我們把數(shù)據(jù)庫建立起來,通過以下命令執(zhí)行數(shù)據(jù)庫遷移:
php artisan migrate
然后在?config/app.php注冊服務(wù)提供者。請確定將代碼放于以下位置:
/* * Application Service Providers... */ AppProvidersAppServiceProvider::class, AppProvidersAuthServiceProvider::class, // AppProvidersBroadcastServiceProvider::class, AppProvidersEventServiceProvider::class, AppProvidersRouteServiceProvider::class, AppProvidersTenancyServiceProvider::class, // <-- 放于此處
現(xiàn)在,我們創(chuàng)建一個自定義的 tenant 模型。該程序包是不受限制的,因此要使用單獨的數(shù)據(jù)庫和域,我們需要創(chuàng)建一個略微定制的 tenant 模型。使用以下代碼創(chuàng)建一個 app/Tenant.php 文件:
<?php namespace App; use StanclTenancyDatabaseModelsTenant as BaseTenant; use StanclTenancyContractsTenantWithDatabase; use StanclTenancyDatabaseConcernsHasDatabase; use StanclTenancyDatabaseConcernsHasDomains; class Tenant extends BaseTenant implements TenantWithDatabase { use HasDatabase, HasDomains; }
現(xiàn)在,我們告訴程序包將該模型用于 tenants:
// config/tenancy.php file 'tenant_model' => AppTenant::class,
兩個部分
軟件包將您的應(yīng)用程序視為兩個獨立的部分:
- central 應(yīng)用程序 —— 承載登錄頁面,可能是管理 tenants 的中央儀表板等
- tenant 應(yīng)用程序 —— 這是您的用戶 (tenants) 使用的部分。這很可能是大多數(shù)業(yè)務(wù)邏輯都存在的地方
拆分應(yīng)用
了解了這兩個部分,讓我們將應(yīng)用進行相應(yīng)的拆分。
Central app
首先讓我們確保 central 應(yīng)用僅在中心域上可訪問。
轉(zhuǎn)到 app/Providers/RouteServiceProvider.php,并確保您的 web 和 api 路由僅在中央域上加載:
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'); }
現(xiàn)在轉(zhuǎn)到您的文件 config/tenancy.php,實際添加中心域。
我使用的是 Valet,所以對我來說,中心域是 saas.test,租戶域以 foo.saas.test 和bar.saas.test 為例。
因此,我們設(shè)置 central_domains 鍵:
'central_domains' => [ 'saas.test', // Add the ones that you use. I use this one with Laravel Valet. ],
Tenant app
現(xiàn)在是有趣的部分。這一部分幾乎太簡單了。
要使某些代碼具有租戶意識,您只需執(zhí)行以下操作:
- 將遷移移動到 tenant/ 目錄
- 將路由移動到 tenant.php 路由文件
就是這樣。
在該特定文件夾中進行遷移并且在該特定路由文件中包含路由將通知包標識該路由上的租戶。
如果您有現(xiàn)有的應(yīng)用程序,請使用您的代碼執(zhí)行此操作。如果您使用的是全新應(yīng)用,請按照以下示例操作:
默認情況下,您的租戶路由如下所示:
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 (非中心) 域上訪問 —— PreventAccessFromCentralDomains 中間件會強制執(zhí)行這一點。
讓我們做一點小更改以轉(zhuǎn)儲數(shù)據(jù)庫中的所有用戶,以便我們可以實際看到多租戶工作。將此添加到中間件組:
Route::get('/', function () { dd(AppUser::all()); return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id'); });
現(xiàn)在,遷移。只需將與租戶應(yīng)用程序相關(guān)的遷移移動到database/migrations/tenant目錄中即可。
因此,對于我們的示例:要使用戶進入租戶數(shù)據(jù)庫,讓我們將users表遷移移至數(shù)據(jù)庫/遷移/租戶。這將防止在中央數(shù)據(jù)庫中創(chuàng)建表,而是在創(chuàng)建租戶時在租戶數(shù)據(jù)庫中創(chuàng)建表。
嘗試一下
現(xiàn)在讓我們創(chuàng)建一些租戶。
我們還沒有可供租戶注冊的登錄頁面,但是我們可以在修補程序中創(chuàng)建他們!
因此,讓我們打開php artisan tinker并創(chuàng)建一些租戶。租戶實際上只是模型,因此您可以像其他任何Eloquent模型一樣創(chuàng)建它們。
請注意,我們在 這里使用域標識因此,請確保您使用的域指向您的應(yīng)用程序。我正在使用代客,所以我正在*.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']);
現(xiàn)在,我們將在每個租戶的數(shù)據(jù)庫中創(chuàng)建一個用戶:
AppTenant::all()->runForEach(function () { factory(AppUser::class)->create(); });
就是這樣-??我們有一個多租戶應(yīng)用程序!
如果您訪問??foo.saas.test?(或與您的環(huán)境相當(dāng)),則會看到用戶轉(zhuǎn)儲。
如果訪問bar.saas.test,您將看到不同用戶的轉(zhuǎn)儲 ?。數(shù)據(jù)庫是100%分離的,我們使用的代碼 —AppUser::all()— 根本不需要了解租約!這一切都會在后臺自動發(fā)生。您只需像以前那樣編寫應(yīng)用程序,而不必考慮自己的范圍界定,并且一切都正常。
當(dāng)然,現(xiàn)在,租戶應(yīng)用程序中將有一個更復(fù)雜的應(yīng)用程序。僅轉(zhuǎn)儲用戶的SaaS可能用處不大。這就是您的工作-編寫將由租戶使用的業(yè)務(wù)邏輯。包裝將處理其余部分。
不過,Tenancy for Laravel ?項目的幫助并沒有到此結(jié)束。該軟件包將為您完成與多租戶相關(guān)的所有繁重工作。但是,如果您要構(gòu)建SaaS,則仍然需要自己編寫計費邏輯,入門流程和類似的標準內(nèi)容。如果您有興趣,該項目還提供了一個優(yōu)質(zhì)產(chǎn)品:Laravel。它旨在通過為您提供通常需要編寫的SaaS功能來節(jié)省您的時間。所有這些都打包在一個隨時可以部署的多租戶應(yīng)用程序中。
原文地址:https://laravel-news.com/multi-tenant
譯文地址:https://learnku.com/laravel/t/47951