У меня есть начальная страница, на которой есть раскрывающийся список из 5 вариантов. 5 вариантов — это 5 разных баз данных. Функциональность, которую мне нужно достичь, одинакова для всех баз данных. Если я выберу вариант А, я хочу, чтобы он подключился к базе данных А и выдал мне результаты в представлении А. Если я выберу вариант B, он должен подключиться к базе данных B и по-прежнему выдавать мне результаты в представлении A.
Я не хочу создавать несколько просмотров одного и того же. Есть ли способ достичь вышеуказанной функциональности?
Спасибо






У вас есть несколько подключений к разным базам данных в config/database.php? Если нет, вы можете создать несколько связей, например database_a и database_b. Если у вас уже есть несколько подключений к разным базам данных, вы можете выбрать подходящее соединение в зависимости от получаемых запросов.
use Illuminate\Support\Facades\DB;
$users = DB::connection('yourdatabase')->select(/* ... */);
Дополнительную информацию см. в разделе Использование нескольких подключений к базе данных документации Laravel.
Вы можете просто изменить соединение запроса к базе данных в зависимости от значения, отправленного в качестве выбранного параметра.
<select name = "database_id">
<option value = "A">Database A</option>
<option value = "B">Database B</option>
<option value = "C">Database C</option>
...
</select>
public function your_endpoint_here(Request $request)
{
$map = [
'A' => ['db' => 'db_a', 'view' => 'view_a'],
'B' => ['db' => 'db_b', 'view' => 'view_b'],
'C' => ['db' => 'db_c', 'view' => 'view_c'],
...
];
$data = DB::connection($map[$request->database_id]['db'])
->from($map[$request->database_id]['view'])
...
->get();
// return $data as json or return view with $data
}
Или, альтернативно, ваше соединение с БД может быть частью или URL-адресом.
Если вам нужно использовать только одну базу данных одновременно, вы можете просто изменить базовое соединение MySQL, но вы также можете объявить новые соединения по мере необходимости в файле config/database.php.
return [
'connections' => [
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
// ...
],
'another_name' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
// ...
],
],
];
Предположим, что выбор базы данных происходит по URL-адресу /login, а использование базы данных происходит по всем маршрутам, начинающимся с /admin. Вы можете объявить промежуточное программное обеспечение, которое будет связано с каждым маршрутом, начинающимся с /admin, и для такого маршрута оно будет устанавливать имя выбранной базы данных.
По URL-адресу /login вы можете сохранить имя выбранной базы данных в переменную сеанса. После этого вы перенаправляете пользователя на /admin/tables или какую-либо домашнюю страницу, где запускается промежуточное программное обеспечение. Затем промежуточное программное обеспечение использует переменную сеанса, получает запрошенное имя базы данных и устанавливает его в соединении следующим образом.
/* app/Http/Middlewares/DatabaseSelector.php */
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
class DatabaseSelector
{
public function handle(Request $request, Closure $next)
{
if (! $request->session()->exists('selectedDatabase')) {
return redirect()->to('login');
}
$databaseName = $request->session()->get('selectedDatabase');
if (config('database.connections.another_name.database') !== $databaseName) {
DB::disconnect('another_name');
Config::set('database.connections.another_name.database', $databaseName);
DB::reconnect('another_name');
}
return $next($request);
}
}
/* app/Http/Kernel.php */
protected $routeMiddleware = [
// Other middleware declarations...
'DatabaseSelector' => \App\Http\Middleware\DatabaseSelector::class,
];
/* routes/web.php */
Route::prefix('admin')->middleware('DatabaseSelector')->group(function () {
// Define routes under /admin here
Route::get('/', function () {
// Your route logic here
});
// Add more routes as needed
});
Таким образом, на каждом маршруте /admin, где работает DatabaseSelector, вы можете использовать DB::connection('another_name') для запроса. Вы можете связать с ним модели Eloquent, установив для параметра $connection значение another_name в файле модели и т. д.
Соединение с именем another_name всегда будет подключаться к базе данных с выбранным именем. На странице /login его единственная задача — точно записать имя базы данных в переменную сеанса selectedDatabase, выбрав одну из 5 доступных баз данных.
/* routes/web.php */
Route::get('/login', 'DatabaseController@showSelectDatabase')->name('login');
Route::post('/login', 'DatabaseController@selectDatabase');
/* app/Http/Controllers/DatabaseController.php */
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class DatabaseController extends Controller
{
public function showSelectDatabase()
{
$databases = ['database1', 'database2', 'database3', 'database4', 'database5'];
return view('login', ['databases' => $databases]);
}
public function selectDatabase(Request $request)
{
$selectedDatabase = $request->input('selectedDatabase');
Session::put('selectedDatabase', $selectedDatabase);
return redirect('/admin');
}
}
<!-- login blade -->
<ul>
@foreach($databases as $database)
<li>
<!-- this Route::post calls the login and passes it the hidden input field, there is one separate form for each of your databases -->
<form method = "post" action = "{{ route('login') }}">
@csrf
<input type = "hidden" name = "selectedDatabase" value = "{{ $database }}">
<button type = "submit">{{ $database }}</button>
</form>
</li>
@endforeach
</ul>
Конечно, я пытался продемонстрировать логику. Попробуйте интерпретировать и подумать, какая логика вам понадобится. Ключевым моментом является то, что вы можете объявлять соединения и изменять их данные во время выполнения на основе описания. Я предоставил вам пример, в котором вы можете выбрать базу данных по URL-адресу /login, а промежуточное программное обеспечение, вызываемое по URL-адресу /admin, автоматически проверит и установит ее в конфигурации.