我正在启动一个 SaaS,为了避免拥有太大的数据库,并帮助调试,我希望每个用户都使用自己的数据库,而不重复 laravel 应用程序。
我一直建议使用一个中间件来切换到用户数据库,具体取决于路由(对于身份验证、配置文件边缘等其他路由,所有用户将使用相同的公共数据库)。
这是我的中间件:
class DatabaseSwitcher
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (Auth::check())
{
$user = Auth::user();
if ($user->email === '[email protected]') // example
{
Log::info('Current database connection: ' . DB::connection()->getDatabaseName());
// Use a specific database for this user
Config::set('database.connections.mysql.database', 'xbot_user1');
Log::info('Current database connection: ' . DB::connection()->getDatabaseName());
DB::purge('mysql'); // this line cause an exception
Log::info('Current database connection: ' . DB::connection()->getDatabaseName());
$connection = DB::connection('mysql');
if (!$connection) {
throw new \Exception("Failed to establish a database connection.");
}
DB::reconnect('mysql'); // Reconnecte avec la nouvelle configuration
Log::info('Current database connection: ' . DB::connection()->getDatabaseName());
}
}
return $next($request);
}
}
因为 DB::purge('mysql'); 我得到了:
Call to a member function prepare() on null {"userId":22,"exception":"[object] (Error(code: 0): Call to a member function prepare() on null at /home/nicolas/Desktop/projets-web/twitterbot/vendor/laravel/framework/src/Illuminate/Database/Connection.php:592)
[stacktrace]
#0 /home/nicolas/Desktop/projets-web/twitterbot/vendor/laravel/framework/src/Illuminate/Database/Connection.php(812): Illuminate\\Database\\Connection->Illuminate\\Database\\{closure}()
真正奇怪的是,当我删除清除功能时,我没有异常, bubDB::connection()->getDatabaseName()) 返回以前的数据库,所以看起来数据库没有切换,但是在我的观点是,当我显示用 eloquent 获取的数据时,会返回用户数据库中的数据)。
所以它似乎没有使用 DB::connection()->getDatabaseName()) 返回的相同数据库
顺便问一下,这是一个好方法吗?或者有什么更好的办法吗?我确信大型 SaaS 不会让所有用户都使用相同的数据库。
谢谢
我必须使用文件进行会话才能使其正常工作。
在 .env 文件中:
SESSION_DRIVER=文件
而不是
SESSION_DRIVER=数据库