The following tutorial column will introduce to you how to make Laravel applications have multi-tenant functions in a few minutes. I hope it will be helpful to friends in need!
In this tutorial, we will useTenancy for Laravel package to make Laravel applications multi-tenant.
It is a multi-tenant software package that allows your Laravel application to be multi-tenant No need to copy additional code
. It's as plug-and-play as a rental package.
Side note: In this tutorial, we'll cover the most common setup - multi-database tenancy on multiple domains. If you need a different setup, this is 100% possible. Just check out the package.
How it worksWhat is unique about this package is that it does not force you to write your application in a specific way. You can write your application as you are used to and it will automatically generate multi-tenancy under the hood. You can even integrate packages into existing applications.
1. When the server receives a user request
2. The program can identify which tenant the request belongs to through the request. (Through the main domain name, subdomain name, path, request header, query parameters, etc.)3. The program will switch from the
default database link to the current tenant link.
4. Any database calls, cache calls, queue calls, and other operations will automatically match the tenant and switch.
Installation
The first step is to install the package through composer. The command is as follows:
composer require stancl/tenancy
command as follows:
php artisan tenancy:install
This operation will generate the following files: migration files, configuration files, routing files and a service provider. Let us set up the database and perform database migration through the following command:
php artisan migrate
Then register the service provider in
config/app.php. Please make sure to place the code in the following location:
/* * 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, // <-- 放于此处
Now, we create a custom tenant model. The package is unrestricted, so to use a separate database and domain we need to create a slightly customized tenant model. Create a app/Tenant.php
file with the following code:
<?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; }
Now we tell the package to use this model for tenants: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">// config/tenancy.php file
&#39;tenant_model&#39; => \App\Tenant::class,</pre><div class="contentsignin">Copy after login</div></div>Two parts<p>The package treats your application as two separate parts: </p>
<h2></h2>central application - hosts the login page, possibly a central dashboard to manage tenants, etc.<p></p>tenant Application - This is the part used by your tenants. This is most likely where most of the business logic resides<ul>
<li>Split the Application<li>Now that we understand these two parts, let’s split the application accordingly. </ul>
<h2>Central app</h2>
<p>First let’s make sure the central app is only accessible on the central domain. </p>
<h3>Go to </h3>app/Providers/RouteServiceProvider.php<p> and make sure your </p>web<p> and <code>api
routes are only loaded on the central domain: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">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');
}</pre><div class="contentsignin">Copy after login</div></div>
Now go to your file config/tenancy.php
and actually add the central domain.
I'm using Valet, so for me the central domain is saas.test
and the tenant domains are
and bar .saas.test
is an example. So we set the
central_domains
key:
'central_domains' => [ 'saas.test', // Add the ones that you use. I use this one with Laravel Valet. ],
Tenant app Now comes the fun part. This part is almost too easy.
tenant/
directorytenant.php
routing file That's it.
If you have an existing application, use your code to do this. If you are using a brand new application, please follow the following example:
By default, your tenant routes look like this:
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'); }); });
These routes can only be used in the tenant (non-hub) domain Access on -
PreventAccessFromCentralDomainsmiddleware enforces this.
Let's make a small change to dump all the users in the database so we can actually see multi-tenancy working. Add this to the middleware group: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">Route::get('/', function () {
dd(\App\User::all());
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
});</pre><div class="contentsignin">Copy after login</div></div>
Now, migrate. Just move the migrations related to the tenant application into the
directory.
因此,对于我们的示例:要使用户进入租户数据库,让我们将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
The above is the detailed content of Teach you how to make your Laravel application multi-tenant in a few minutes. For more information, please follow other related articles on the PHP Chinese website!