Natknąłem się na to pytanie i miał moją odpowiedź.
Utworzyłem klasę o nazwie DatabaseConnection
:
class DatabaseConnection extends Model
{
static $instances=array();
protected $database;
protected $connection;
public function __construct($options = null)
{
// Set the database
$database = $options['database'];
$this->database = $database;
// Figure out the driver and get the default configuration for the driver
$driver = isset($options['driver']) ? $options['driver'] : Config::get("database.default");
$default = Config::get("database.connections.$driver");
// Loop through our default array and update options if we have non-defaults
foreach($default as $item => $value)
{
$default[$item] = isset($options[$item]) ? $options[$item] : $default[$item];
}
$capsule = new Capsule;
$capsule->addConnection($default);
$capsule->setEventDispatcher(new Dispatcher(new Container));
$capsule->setAsGlobal();
$capsule->bootEloquent();
// Create the connection
$this->connection = $capsule->getConnection();
DatabaseConnection::$instances[] = $capsule;
return $this->connection;
}
}
Tak więc, ilekroć jestem w kontrolerze, który manipuluje tabelami podbazy danych, po prostu idę w ten sposób:
public function RandomActionInMyController()
{
$db_connection = new DatabaseConnection(['database' => 'name_of_db']);
$someModel = new Model/Model::find()..// Basically anything
return myreturnstuff;
}
Dodatkowy bonus :
Użycie statycznego atrybutu $instances
w moim DatabaseConnection
sprowadza się do odzyskania mojego najnowszego połączenia z bazą danych w celu ułatwienia użytkowania.
Na przykład, gdybym kiedykolwiek chciał go pobrać, zostałby opakowany w funkcję taką jak
function CurrentOrLatestDbConnection()
{
if( !empty(DatabaseConnection::$instances) )
{
return end(DatabaseConnection::$instances)->getConnection()->getDatabaseName();
}
}
Notatki :
Jeśli napotkasz błędy, takie jak Unknown class 'Container'
lub Capsule
lub cokolwiek w tym rodzaju, sprawdź podany przeze mnie link do pytania i użyj use
oświadczenia prawidłowo.
Dotyczące nadchodzących odpowiedzi :
Wydaje mi się, że to połączenie z bazą danych znajduje się w nawiasach akcji kontrolera, więc kiedy przechodzę do innej akcji, która nie określa żadnego połączenia, automatycznie powraca ono do centralnej bazy danych.
Co sprawiło, że pomyślałem, że musi istnieć sposób na ustawienie połączenia bazy danych z podbazą danych w sposób „globalny” dla całej funkcji, takiej jak oprogramowanie pośredniczące lub coś takiego.
Chciałbym zobaczyć odpowiedź, wdrażając takie rzeczy.
Aktualizacja :
Wymyśliłem ładniejszy sposób na zrobienie tego.
Zakładam, że jesteś na tym samym gruncie co ja, chcąc zmienić bazy danych warunkowo zgodnie z każdym kontrolerem... powiedzmy, każdy z twoich kontrolerów wymaga innej bazy danych, tylko ze względu na argument.
To, czego użyjemy do rozwiązania tego problemu, to oprogramowanie pośrednie.
Po pierwsze, aby wyjaśnić, co zamierzamy zrobić...
Sprawdzimy nazwę kontrolera (a nawet akcję), a następnie ustawimy odpowiednią bazę danych, którą chcemy ustawić.
-
Przejdź do wiersza poleceń , wpisz:
php artisan make:middleware SetDatabaseConnectionMiddleware
Aby stworzyć oprogramowanie pośrednie z gotowym boilerplate’em.
Lub, jeśli podoba Ci się to w trudny sposób, przejdź do swojej app_name/app/Http/Middleware i utwórz je ręcznie.
-
Przejdź do pliku metod pomocniczych (jeśli już masz, jeśli nie, zrób to!)
Funkcjafunction getControllerAndActionName() { $action = app('request')->route()->getAction(); $controller = class_basename($action['controller']); list($controller, $action) = explode('@', $controller); return ['action' => $action, 'controller' => $controller]; }
Spowoduje to zwrócenie tablicy z nazwą akcji i nazwą kontrolera, jeśli chcesz zwracać tylko nazwę kontrolera, możesz usunąć 'action' => $action
z kodu.
- Wewnątrz oprogramowania pośredniczącego będzie to wyglądać tak:
Przestrzeń nazw
namespace App\Http\Middleware;
use Closure;
use DatabaseConnection;
class SetProperDatabase
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$database_name = '';
$controllerAndActionName = getControllerAndActionName();
$controller_name = $controllerAndActionName['controller'];
$action_name = $controllerAndActionName['action'];
if($controller_name == 'my_controller_nameController')
{
$database_name = 'your_proper_database_name';
}
else
{
$database_name = 'other_db';
}
$database_connection = new DatabaseConnection(['database' => $database_name']);
return $next($request);
}
}
4. Teraz, gdy poprawnie utworzyłeś oprogramowanie pośredniczące, pozwól nam powiedzieć Twojej aplikacji, gdzie je znaleźć i pod jaką nazwą.
- Przejdź do aplikacji nazwa_aplikacji/app/Http/Kernel.php
-
W swoim
$routeMiddleware
zmienna, dodaj tę linię'set_proper_database' => \App\Http\Middleware\SetProperDatabase::class,
W ten sposób wiemy, jak to nazwać.
-
Na koniec konfiguracja.
- Przejdź do swojego
Controller.php
(klasa Abstract, z której dziedziczą wszystkie kontrolery)
public function __construct()
{
$this->middleware('set_proper_database');
}
- Przejdź do swojego
I to powinno zrobić to za ciebie.
Jeśli masz dodatkowe pytania, możesz je skomentować.
// Zasoby :
2.Dokumentacja oprogramowania pośredniego
3.Dalsza dokumentacja oprogramowania pośredniego Notatki :Byłbym wdzięczny za wydanie niektórych zmian dotyczących mojego stylu i wcięć kodu, ponieważ wygląda na to, że miałem problemy z właściwym stylem kodu tutaj, ale na próżno, wcięcia, których użyłem, nie zadziałały.