Попаднах на този въпрос и имаше моя отговор.
Направих клас, наречен 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;
}
}
Така че, когато съм в контролер, който манипулира таблици на подбаза данни, просто вървя по този начин:
public function RandomActionInMyController()
{
$db_connection = new DatabaseConnection(['database' => 'name_of_db']);
$someModel = new Model/Model::find()..// Basically anything
return myreturnstuff;
}
Допълнителен бонус :
Използването на статичен атрибут $instances
в моята DatabaseConnection
се свежда до извличане на най-новата ми връзка с база данни за по-лесно използване.
Например, ако някога съм искал да го извлека, той ще бъде обвит във функция като
function CurrentOrLatestDbConnection()
{
if( !empty(DatabaseConnection::$instances) )
{
return end(DatabaseConnection::$instances)->getConnection()->getDatabaseName();
}
}
Бележки :
Ако срещнете грешки като Unknown class 'Container'
или Capsule
или нещо от този вид, уверете се, че сте проверили връзката към въпроса, която предоставих, и използвайте use
изявления правилно.
Относно предстоящите отговори :
Струва ми се, че тази връзка към базата данни живее в скобите на действието на контролера, така че когато продължа към друго действие, което не посочва връзка, тя се връща автоматично към централната база данни.
Което ме накара да се замисля, че трябва да има начин да настроя връзката към базата данни към подбазата по „глобален“ начин към цялата функция, като междинен софтуер или нещо подобно.
Бих искал да видя отговор, внедряване на такова нещо.
Актуализиране :
Измислих по-чист начин да го направя.
Предполагам, че сте на същото основание като мен, като искате да промените базите данни условно в съответствие с всеки контролер... да речем, всеки от вашите контролери изисква различна база данни, само в името на аргумента.
Това, което ще използваме, за да решим това, е `Middlewares.
Първо, да обясним какво ще правим...
Ще проверим за името на контролера (и дори действието) и след това ще зададем правилната база данни, която искаме да зададем.
-
Отидете на командния ред, въведете:
php artisan make:middleware SetDatabaseConnectionMiddleware
За да създадете междинен софтуер с готов шаблон.
Или, ако ви харесва по трудния начин, отидете на вашето app_name/app/Http/Middleware и създайте ръчно.
-
Отидете до вашия файл с помощни методи (ако вече имате такъв, ако не, пич, направете такъв!)
function getControllerAndActionName() { $action = app('request')->route()->getAction(); $controller = class_basename($action['controller']); list($controller, $action) = explode('@', $controller); return ['action' => $action, 'controller' => $controller]; }
Това ще ви върне масив както с името на действието, така и с името на контролера, ако искате да върнете ограничено само името на контролера, не се колебайте да премахнете 'action' => $action
от кода.
- Вътре във вашия междинен софтуер той ще изглежда по следния начин:
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.Сега, след като сте създали правилно своя междинен софтуер, нека кажем на приложението ви къде да го намери и под какво име.
- Отидете на вашето app_name/app/Http/Kernel.php
-
Във вашия
$routeMiddleware
променлива, добавете този ред'set_proper_database' => \App\Http\Middleware\SetProperDatabase::class,
По този начин знаем как да го наречем.
-
И накрая, настройването му.
- Отидете на вашия
Controller.php
(Абстрактният клас, от който наследяват всичките ви контролери)
public function __construct()
{
$this->middleware('set_proper_database');
}
- Отидете на вашия
И това трябва да го направи вместо вас.
Ако имате допълнителни въпроси, моля не се колебайте да коментирате.
// Ресурси :
2.Документация за междинен софтуер
3.Допълнителна документация за междинен софтуер Бележки :Бих оценявал някое издание относно стила и отстъпа на кода, тъй като изглежда, че се мъчих да стилизирам правилно кода си тук, но напразно, отстъпите, които използвах, нямаха ефект.