Когда конфигурация инициализируется для приложения Laravel? или когда DB :: соединение установлено? - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть промежуточное программное обеспечение, которое динамически изменяет конфигурацию базы данных следующим образом:

config(['database.connections.mysql.database'=> 'newDatabaseName']);

И в каждой модели у меня явно установлено $connection = 'mysql'.

Внутри моего конструктора модели:

logger()->info(get_class($this). ' database: ' . config('database.connections.mysql.database'));
logger()->info(get_class($this). ' database: ' . DB::connection($this->connection)->getDatabaseName());

Вывод:

newDatabaseName
oldDatabaseName

, где newDatabaseName - база данных, которую я установил в промежуточном программном обеспечении, и oldDatabasename это имя базы данных .env.

Так что в основном я успешно установил имя базы данных в конфигурации, но модель по-прежнему использует имя базы данных .env по какой-то причине.

Есть идеи, почему это происходит?

У меня есть другие промежуточные программы, применяемые к этим маршрутам:

SubstituteBindings::class,
ChangeLocale::class,
HandleCors::class,

Я думал, что это из-за промежуточного программного обеспечения "SubstituteBinding", но я пытался поставить свое промежуточное ПО до и после него, это не имеет значения.

Я использую laravel 5.6

Ответы [ 3 ]

0 голосов
/ 06 апреля 2020

Laravel выбирает и сохраняет конфигурации в массиве при начальной загрузке приложения.

Когда приложение запускается, оно считывает конфигурации базы данных и инициирует соединение с базой данных на основе конфигураций, которые вы переопределите в промежуточном программном обеспечении. Таким образом, обновление конфигов соединения с базой данных не повлияет на само соединение.

Решение:

Определите несколько соединений в config/database.php, затем установите имя соединения по умолчанию в вашем промежуточное программное обеспечение вместо установки имени базы данных.

config(['database.default' => $connectionName]);

И, конечно, не устанавливайте имя соединения в моделях явно.

0 голосов
/ 07 апреля 2020

Я наконец нашел, что происходит. DatabaseManager кэширует все соединения в первый раз, это исправит это:

config(['database.connections.mysql.database' => 'newDatabaseName']);

DB::purge('mysql');

DB::reconnect('mysql');

Вот пост, который я нашел, который говорит о точной проблеме: https://divinglaravel.com/understanding-how-laravel-configures-database-connections

0 голосов
/ 06 апреля 2020

Вы можете динамически устанавливать базы данных. Это переопределит файл .evn и config/database.php.

class MyMiddleware
{
    public function handle($request, Closure $next)
    {
        Config::set('database.connections.mysql.database', $request->path());

        return $next($request);
    }
}

Ядро

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        MyMiddleware::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

Теперь протестируйте его! Если у вас есть две базы данных laravel и stTest. И поле имени в пользовательской таблице также stTest и laravel.

Route::get('/stTest', function () {
    return User::first()->name; //stTest
});

Route::get('/laravel', function () {
    return User::first()->name; //laravel
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...