airdjura / laravel-multitenancy
为Laravel提供的一个简单、单数据库多租户解决方案
Requires
- php: >=5.6.0
- illuminate/support: 5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|6.0.*|7.0.*|8.0.*|8.43.0|9.*
Requires (Dev)
- laravel/framework: 5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|6.0.*|7.0.*|8.0.*|8.43.0|9.*
- mockery/mockery: ~0.9|~1.0
- phpunit/phpunit: 5.5.*|6.0.*|7.0.*
This package is auto-updated.
Last update: 2024-09-27 16:40:04 UTC
README
为Laravel提供的单数据库多租户包
从Landlord v1升级? 请确保阅读变更日志,了解需要更新的内容。
安装
要开始使用,请要求此包
composer require airdjura/laravel-multitenancy
Laravel
在config/app.php
中添加ServiceProvider
'providers' => [ ... airDjura\Landlord\LandlordServiceProvider::class, ],
如果你想要,注册Facade
'aliases' => [ ... 'Landlord' => airDjura\Landlord\Facades\Landlord::class, ],
你也可以发布配置文件
php artisan vendor:publish --provider="airDjura\Landlord\LandlordServiceProvider"
并设置你的default_tenant_columns
设置,如果你有一个全局默认值。Landlord将使用此设置来限制没有设置$tenantColumns
属性的模型。
Lumen
你需要在bootstrap/app.php
中设置ServiceProvider
$app->register(airDjura\Landlord\LandlordServiceProvider::class);
并确保你已经取消注释了$app->withEloquent()
。
用法
此包假定你在所有租户作用域的表中至少有一个列,该列引用了每行属于哪个租户。
例如,你可能有一个companies
表,以及一些其他表,这些表都有一个company_id
列。
添加和删除租户
重要提示:Landlord是无状态的。这意味着当你调用
addTenant()
时,它只会作用在当前请求上。确保你以这种方式添加租户,使其在每次请求时发生,并且在需要作用域模型之前,如在中间件或作为无状态的认证方法(如OAuth)的一部分。
你可以通过调用addTenant()
来告诉Landlord自动作用域特定的租户,无论是从Landlord
Facade还是通过注入一个TenantManager()
实例。
你可以传递一个租户列和ID
Landlord::addTenant('tenant_id', 1);
或一个租户模型实例
$tenant = Tenant::find(1); Landlord::addTenant($tenant);
如果你传递一个模型实例,Landlord将使用Eloquent的getForeignKey()
方法来决定租户列的名称。
你可以添加任意多的租户,但是Landlord一次只允许一个类型的租户。
要删除租户并停止通过它作用域,只需调用removeTenant()
Landlord::removeTenant('tenant_id'); // Or you can again pass a Model instance: $tenant = Tenant::find(1); Landlord::removeTenant($tenant);
你也可以检查Landlord当前是否正在通过特定的租户作用域
// As you would expect by now, $tenant can be either a string column name or a Model instance Landlord::hasTenant($tenant);
如果需要,你可以检索Landlord的租户
// $tenants is a Laravel Collection object, in the format 'tenant_id' => 1 $tenants = Landlord::getTenants();
设置你的模型
要设置一个自动作用域的模型,只需使用BelongsToTenants
特质
use Illuminate\Database\Eloquent\Model; use airDjura\Landlord\BelongsToTenants; class ExampleModel extends Model { use BelongsToTenants; }
如果你想要覆盖特定模型应用的租户,你可以设置$tenantColumns
属性
use Illuminate\Database\Eloquent\Model; use airDjura\Landlord\BelongsToTenants; class ExampleModel extends Model { use BelongsToTenants; public $tenantColumns = ['tenant_id']; }
创建新的租户作用域模型
当你创建一个使用BelongsToTenants
的模型的新实例时,如果它们尚未设置,Landlord将自动添加任何适用的租户ID
// 'tenant_id' will automatically be set by Landlord $model = ExampleModel::create(['name' => 'whatever']);
查询租户作用域模型
添加租户后,对使用BelongsToTenant
的模型的任何查询都将自动作用域
// This will only include Models belonging to the current tenant(s) ExampleModel::all(); // This will fail with a ModelNotFoundForTenantException if it belongs to the wrong tenant ExampleModel::find(2);
注意:当你开发一个多租户应用程序时,有时可能会有些困惑,为什么你总是收到针对确实存在的行的
ModelNotFound
异常,因为它们属于错误的租户。Landlord将捕获这些异常,并将它们重新抛出为
ModelNotFoundForTenantException
,以帮助你解决问题 :)
如果您需要跨所有租户进行查询,可以使用 allTenants()
// Will include results from ALL tenants, just for this query ExampleModel::allTenants()->get()
在底层,Landlord 使用 Laravel 的 匿名全局作用域。这意味着如果您同时针对多个租户进行作用域操作,并且想在一个查询中排除其中一个,您可以这样操作
// Will not scope by 'tenant_id', but will continue to scope by any other tenants that have been set ExampleModel::withoutGlobalScope('tenant_id')->get();
贡献
如果您发现了一个问题,或者有更好的实现方法,请随意提交一个 issue 或 pull request。