Laravel 5 - 一个服务器/多个数据库由请求决定
Laravel 5 - One server / multiple databases determined by request
所以我正在开发一个有两种部署的应用程序。一是他们托管一切,只有一个应用程序/一个数据库,没有问题。第二个(这个问题将围绕的那个)将有一个应用程序,但每个客户端有不同的数据库连接。
对每个域的访问都将是 white-listed,因此我们不必担心一个客户端会突然弹出另一个客户端域,并且它们是在此之上的其他身份验证。
我需要的是two-fold:
- 一种确定正在访问应用程序的客户端的方法(请求headers?域驱动?)
- 获取所述客户端的配置,以便他们仅访问其数据库信息(使用基于客户端的特定 .env 文件?)。
我想到的一个想法是使用 apache 根据请求的域设置环境变量。但是,我更愿意将此处理保留在 laravel 内。有什么想法吗?
我们就是这样做的。如您所述,您需要一些可以将域映射到客户端的权限,然后才能获取特定于客户端的设置。
以下是我们的设置方式:
我们每个客户端都有不同的 Apache 虚拟主机,所有 domains/aliases 客户端都已设置。在 vhost 文件中,Apache 给了我们一个环境变量 CLIENT_ID
。这样我们就知道客户是谁,无论在任何时候使用哪个域别名。
我们有一个 Laravel 服务提供商,然后查看 env('CLIENT_ID')
并设置许多配置选项。设置的内容之一是特定于客户端的路径,我们在其中存储许多特定于客户端的资源和文件。所以我们正在做这样的事情:
Config::set("paths.client", "/var/www/clients/" . env("CLIENT_ID"));
现在我们已经设置了特定于客户端的路径,我们可以使用 Dotenv
为该客户端加载特定于客户端的 .env
文件。请注意,我们的应用程序目录中仍然有一个根 .env
文件(Laravel 期望它),它设置了通用配置。特定于客户端的 .env
文件设置特定于客户端的内容,例如 SMTP 设置,当然还有数据库连接设置。
Dotenv::load(Config::get("paths.client"));
现在特定于客户端的 .env
已加载,我们可以轻松写入 database.connections
配置数组。从那时起,eloquent 和其他一切正常。
Config::set('database.connections.mysql', [
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
]);
你当然不必这样做。我们选择 Apache vhosts 作为我们将域映射到客户端的权威,但您可以有一个主数据库或只有一个配置文件。然后在您的服务提供商中,您只需要询问主数据库(或配置文件)需要设置什么客户端。
如果您不想存储单独的 .env
文件,您的客户端设置甚至可以位于主数据库或配置文件中。您可以通过多种方式为这只猫剥皮。
最终,无论您到达那里,一旦您设置了数据库配置连接数组,您就可以开始了。
更新:
对于以后阅读本文的任何人,还有另一种非常简单的方法来加载备用 .env
文件,如下面的评论所述:
If you set APP_ENV somehow before you get to Laravel (SetEnv in virtualhost etc) it will by default look for .env.APP_ENV (Ex: .env.demo) file. I am using SetEnv to set APP_ENV and then creating .env files for each client.
出于我们的目的,我们不希望特定于客户端的 .env
文件位于我们应用程序的根目录中。但它在其他情况下也能很好地工作。
所以我正在开发一个有两种部署的应用程序。一是他们托管一切,只有一个应用程序/一个数据库,没有问题。第二个(这个问题将围绕的那个)将有一个应用程序,但每个客户端有不同的数据库连接。
对每个域的访问都将是 white-listed,因此我们不必担心一个客户端会突然弹出另一个客户端域,并且它们是在此之上的其他身份验证。
我需要的是two-fold:
- 一种确定正在访问应用程序的客户端的方法(请求headers?域驱动?)
- 获取所述客户端的配置,以便他们仅访问其数据库信息(使用基于客户端的特定 .env 文件?)。
我想到的一个想法是使用 apache 根据请求的域设置环境变量。但是,我更愿意将此处理保留在 laravel 内。有什么想法吗?
我们就是这样做的。如您所述,您需要一些可以将域映射到客户端的权限,然后才能获取特定于客户端的设置。
以下是我们的设置方式:
我们每个客户端都有不同的 Apache 虚拟主机,所有 domains/aliases 客户端都已设置。在 vhost 文件中,Apache 给了我们一个环境变量
CLIENT_ID
。这样我们就知道客户是谁,无论在任何时候使用哪个域别名。我们有一个 Laravel 服务提供商,然后查看
env('CLIENT_ID')
并设置许多配置选项。设置的内容之一是特定于客户端的路径,我们在其中存储许多特定于客户端的资源和文件。所以我们正在做这样的事情:Config::set("paths.client", "/var/www/clients/" . env("CLIENT_ID"));
现在我们已经设置了特定于客户端的路径,我们可以使用
Dotenv
为该客户端加载特定于客户端的.env
文件。请注意,我们的应用程序目录中仍然有一个根.env
文件(Laravel 期望它),它设置了通用配置。特定于客户端的.env
文件设置特定于客户端的内容,例如 SMTP 设置,当然还有数据库连接设置。Dotenv::load(Config::get("paths.client"));
现在特定于客户端的
.env
已加载,我们可以轻松写入database.connections
配置数组。从那时起,eloquent 和其他一切正常。Config::set('database.connections.mysql', [ 'database' => env('DB_DATABASE'), 'username' => env('DB_USERNAME'), 'password' => env('DB_PASSWORD'), ]);
你当然不必这样做。我们选择 Apache vhosts 作为我们将域映射到客户端的权威,但您可以有一个主数据库或只有一个配置文件。然后在您的服务提供商中,您只需要询问主数据库(或配置文件)需要设置什么客户端。
如果您不想存储单独的 .env
文件,您的客户端设置甚至可以位于主数据库或配置文件中。您可以通过多种方式为这只猫剥皮。
最终,无论您到达那里,一旦您设置了数据库配置连接数组,您就可以开始了。
更新:
对于以后阅读本文的任何人,还有另一种非常简单的方法来加载备用 .env
文件,如下面的评论所述:
If you set APP_ENV somehow before you get to Laravel (SetEnv in virtualhost etc) it will by default look for .env.APP_ENV (Ex: .env.demo) file. I am using SetEnv to set APP_ENV and then creating .env files for each client.
出于我们的目的,我们不希望特定于客户端的 .env
文件位于我们应用程序的根目录中。但它在其他情况下也能很好地工作。