Laravel Config::set 通过请求坚持?

Laravel Config::set Persist Through Requests?

我一直在构建一个跟踪统计信息的 Web 应用程序。 这些统计数据可以在不同的公司之间变化。
我决定使用一个主数据库来存放所有登录凭据,并且每个公司都有一个单独的数据库。
用户登录后,他们将被重定向到此功能...

/**
* Redirects the user to the appropriate sub link
*/
public function redirect()
{
    Config::set('database.connections.club.database', Auth::user()->club->db_name);
    if (Auth::user()->person->role_id == 4) {
        return Redirect::to('employee/club_manager/home');
    }
}

此函数将称为俱乐部数据库的辅助数据库配置设置为等于用户关联的俱乐部。

然而,当我稍后尝试访问此配置时...

/**
* Handle an incoming request.
*
* @param  \Illuminate\Http\Request $request
* @param  \Closure $next
* @return mixed`enter code here`
*/
public function handle($request, Closure $next)
{
    dd(Config::get('database.connections.club.database'));
    if (Auth::user()->role->id == 4)
        return $next($request);
}

dd()会return '',这是我在database.php文件中设置的默认设置。

我的问题是,我如何才能跨请求保存配置设置,因为看起来 Config::set 只是为单个请求保存设置。

好吧,你实际上不能为此使用配置。

Configuration values that are set at run-time are only set for the current request, and will not be carried over to subsequent requests.

Laravel 文档 reference

解决方法

作为一个 hacky 解决方法,如果您不愿意使用主数据库来存储公司数据库连接数据,您可以使用可以在 运行 时间更新的自定义配置文件。

这与原始配置文件的工作方式非常相似,它应该持久保存数据。但是你必须围绕它建立一个控制机制来保持条目的唯一性和一致性:

Update Config on Runtime Persistently

您也可以为此寻找一个软件包,这样您就不必重新发明轮子了。检查laravel-config-writer(免责声明:从未亲自使用过)。

根据OP的要求,我提交了第二个答案作为不同的方法。

如果这仅用于数据库连接详细信息,您可以在单个 Laravel 应用程序中对多个数据库连接使用以下方法。

app/config/database.php中您定义了两个不同的连接。一个用于存储 users table 的主数据库,一个用于每个客户端实例的动态:

'default' => 'mysql_main',
'connections' => [

    'mysql_main' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => null,
    ],

    'mysql_company' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', 'localhost'),
        'port' => env('DB_PORT', '3306'),
        'database' => Auth::user()->club->db_name,
        'username' => Auth::user()->club->db_user,
        'password' => Auth::user()->club->db_pass,
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
        'engine' => null,
    ],

],

如您所见,您实际上不需要从配置文件中读取第二个连接的连接详细信息(它仍将用于获取主机、端口和与主数据库的任何公共详细信息),您可以通过来自您登录用户的动态不同的连接详细信息。但是,这将要求您提前为每个用户创建所有数据库。

成功连接到这两个数据库后,您必须在执行查询时随时 select 激活连接。

希望 Schema Builder、Query Builder 和 Eloquent 支持开箱即用:

Shema 生成器

Schema::connection('mysql_company')->create('statisticA', function($table)
{
    $table->increments('id'):
});

查询生成器

$companyStatA = DB::connection('mysql_company')->select(...);

Eloquent 型号

class StatisticA extends Eloquent {

    protected $connection = 'mysql_company';

}

控制器

class SomeController extends BaseController {

    public function someMethod()
    {
        $statA = new StatisticA;

        $statA->setConnection('mysql_company');

        $something = $statA->find(1);

        return $something;
    }

}

然而,棘手的是定义存储在不同数据库中的模型之间的关系。这是可能的,但它在很大程度上取决于您的数据库驱动程序和设置。

我怀疑它能否在不同类型的数据库之间正常运行(例如 MySQL 作为您的主数据库,而 PostgreSQL 作为您公司的数据库),所以我建议您坚持使用 MySQL 和看看进展如何。