让一个用户使用自己的数据库的中间件

问题描述 投票:0回答:1

我正在启动一个 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 不会让所有用户都使用相同的数据库。

谢谢

laravel laravel-middleware laravel-datatables
1个回答
0
投票

我必须使用文件进行会话才能使其正常工作。

在 .env 文件中:

SESSION_DRIVER=文件

而不是

SESSION_DRIVER=数据库

© www.soinside.com 2019 - 2024. All rights reserved.