Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment puis-je me connecter à différentes bases de données au moment de l'exécution ?

Je suis tombé sur cette question et il avait ma réponse.

J'ai créé une classe appelée 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;
        }
}

Ainsi, chaque fois que je suis dans un contrôleur qui manipule des tables d'une sous-base de données, je procède simplement de cette façon :

public function RandomActionInMyController()
{
      $db_connection = new DatabaseConnection(['database' => 'name_of_db']);
       $someModel = new Model/Model::find()..// Basically anything
        return myreturnstuff;
}

Bonus supplémentaire :

L'utilisation de l'attribut statique $instances dans ma DatabaseConnection se résume à récupérer ma dernière connexion à la base de données pour faciliter les utilisations.

Par exemple, si jamais je voulais le récupérer, il serait enveloppé dans une fonction telle que

function CurrentOrLatestDbConnection()
{
    if( !empty(DatabaseConnection::$instances) )
    {
        return end(DatabaseConnection::$instances)->getConnection()->getDatabaseName();
    }
}

Remarques :

Si vous rencontrez des erreurs telles que Unknown class 'Container' ou Capsule ou quoi que ce soit de ce genre, assurez-vous de vérifier le lien de la question que j'ai fourni et d'utiliser use déclarations correctement.

Concernant les réponses à venir :

Il me semble que cette connexion à la base de données vit entre les crochets de l'action du contrôleur, donc lorsque je passe à une autre action qui ne spécifie aucune connexion, elle revient automatiquement à la base de données centrale.

Ce qui m'a fait penser qu'il doit y avoir un moyen de définir la connexion de la base de données à la sous-base de données de manière "globale" à l'ensemble de la fonction, comme un middleware ou autre.

J'aimerais voir une réponse, mettre en œuvre une telle chose.

Mettre à jour :

J'ai trouvé une façon plus propre de le faire.

Je suppose que vous êtes sur le même terrain que moi, voulant modifier les bases de données de manière conditionnelle en fonction de chaque contrôleur... disons, chacun de vos contrôleurs nécessite une base de données différente, juste pour le plaisir de l'argument.

Ce que nous allons utiliser pour résoudre ce problème, ce sont les `Middlewares.

Tout d'abord, pour expliquer ce que nous sommes sur le point de faire..

Nous allons vérifier le nom du contrôleur (et même l'action), puis définir la base de données appropriée que nous souhaitons définir.

  1. Accédez à votre ligne de commande, tapez :

    php artisan make:middleware SetDatabaseConnectionMiddleware

Pour créer un middleware avec un passe-partout prêt.

Ou, si vous l'aimez à la dure, accédez à votre app_name/app/Http/Middleware et créez-en un manuellement.

  1. Allez dans votre fichier de méthodes d'aide (si vous en avez déjà un, sinon, mec, faites-en un !)

     function getControllerAndActionName()
    {
    
    $action = app('request')->route()->getAction();
    
    $controller = class_basename($action['controller']);
    
    list($controller, $action) = explode('@', $controller);
    
    return ['action' => $action, 'controller' => $controller];
    }
    

Cela vous renverra un tableau avec à la fois le nom de l'action et le nom du contrôleur, si vous souhaitez renvoyer uniquement le nom du contrôleur, n'hésitez pas à supprimer 'action' => $action à partir du code.

  1. À l'intérieur de votre middleware, cela ressemblera à ceci :

    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.Maintenant que vous avez correctement créé votre middleware, laissez-nous indiquer à votre application où le trouver et sous quel nom.

  1. Accédez à votre app_name/app/Http/Kernel.php
  2. Dans votre $routeMiddleware variable, ajoutez cette ligne

    'set_proper_database' => \App\Http\Middleware\SetProperDatabase::class,

De cette façon, nous savons comment l'appeler.

  1. Enfin, le configurer.

    1. Allez sur votre Controller.php (la classe abstraite dont héritent tous vos contrôleurs)

    public function __construct() { $this->middleware('set_proper_database'); }

Et cela devrait le faire pour vous.

Si vous avez d'autres questions, n'hésitez pas à commenter.

// Ressources :

1.Nom du contrôleur et de l'action

2.Documentation du middleware

3.Documentation complémentaire sur le middleware Remarques :J'apprécierais une édition concernant mon style et l'indentation du code, car il semble que j'ai eu du mal à styler mon code correctement ici mais en vain, les indentations que j'ai utilisées n'ont eu aucun effet.