这通常是因为租户的数据库没有自动创建,或者应用未能正确切换到租户数据库连接。为了帮助你系统地排查问题,我梳理了一个主要的排查路径:
检查租户数据库创建配置
如果租户数据库根本没有创建,问题通常出在租户创建流程的配置上。
- 「确认租户模型配置」:确保你的
Tenant
模型不仅使用了HasDatabase
和HasDomains
trait,还正确实现了TenantWithDatabase
接口。这是触发数据库自动创建的关键。// app/Models/Tenant.php
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;
} - 「检查租户创建事件监听」:在
TenancyServiceProvider
中,需要确保当TenantCreated
事件触发时,会执行一系列用于创建和初始化数据库的任务(Job Pipeline)。关键任务包括CreateDatabase
和MigrateDatabase
。请检查你的TenancyServiceProvider
中的events
方法是否正确配置了这些任务。// app/Providers/TenancyServiceProvider.php
public function events()
{
return [
TenantCreated::class => [
JobPipeline::make([
Jobs\CreateDatabase::class, // 创建数据库
Jobs\MigrateDatabase::class, // 执行迁移
// Jobs\SeedDatabase::class, // 可选:填充数据
])->shouldBeQueued(false), // 开发环境可设为 false 同步执行
],
];
} - 「验证手动创建流程」:如果事件监听配置看起来没问题,或者你想快速验证,可以尝试手动为已存在的租户运行数据库迁移命令。如果这个命令能成功创建数据库和表结构,说明问题可能出在自动创建的环节。
php artisan tenants:migrate --tenants=foo
检查数据库连接与域名配置
如果确认数据库已经存在,但应用仍然无法连接,那么问题可能出在连接配置或租户识别上。
- 「检查数据库主账号权限」:确保你的
.env
文件中配置的数据库用户(通常是主数据库用户)拥有足够的权限去「创建新的数据库」(对于自动创建场景)或「访问租户数据库」。这个用户需要CREATE
权限。 - 「验证中心数据库连接」:首先确保你的应用能够正常连接中心数据库(即存储
tenants
和domains
表的数据库)。可以尝试执行php artisan db:show
来测试连接。 - 「确认租户域名映射」:确保你为租户创建的域名记录已正确保存在中心数据库的
domains
表中,并且该域名与当前访问的地址完全匹配(包括子域名部分)。你可以通过 Tinker 检查:php artisan tinker
>>> App\Models\Tenant::find('foo')->domains; - 「检查本地域名解析」:在本地开发环境中,确保你的子域名(如
foo.saas.test
)已正确指向你的应用。如果你使用 Laravel Valet,*.test
域名通常是自动通配解析的。如果使用其他方式,请检查你的 Hosts 文件或本地 DNS 配置。
💡 其他排查技巧
- 「查看日志文件」:仔细检查
storage/logs/laravel.log
文件,寻找在租户创建过程或访问租户域名时产生的任何错误信息、SQL 语句或异常堆栈跟踪,这能提供最直接的线索。 - 「清除配置缓存」:在修改了配置文件或服务提供者后,运行以下命令确保所有更改生效:
php artisan config:clear
php artisan cache:clear