5
votes

Définition de la base de données dynamique dans la configuration lors de la connexion - Laravel

J'essaie de modifier la connexion à la base de données lors de la connexion en fonction de l'entreprise de l'utilisateur.

Ici, mon utilisateur a une entreprise et sa base de données est companyA

Ci-dessous est mon LoginController où j'ai changé la connexion:

 Stock::orderBy('tag_no','asc')->get()

Donc, basé sur user-> company qui est déjà défini dans la table des utilisateurs, le nom de la base de données est changé.

Mais d'une manière ou d'une autre, cela ne fonctionne pas. L'erreur affichée est

Aucune base de données sélectionnée.

J'ai essayé le code ci-dessous pour vérifier si les valeurs sont définies lors de la connexion.

protected $table = 'stocks';  
protected $connection = 'dynamicdb';

Il a montré toutes les valeurs définies selon mes exigences. Mais quand je vérifie après la connexion et atteint / home, la valeur de la base de données dans config est nulle.

Alors, que dois-je faire pour tous les changements. Ma technique est-elle correcte? Ou existe-t-il une autre solution pour cela.

Dans mon modèle de stock, j'ai ajouté les lignes ci-dessous:

return \Config::get('database.connections.dynamicdb');

Et la requête que j'exécute est juste une requête get all:

public function authenticated(Request $request,User $user)
{
    \Config::set('database.connections.dynamicdb', array(
        'driver'    => 'mysql', 
        'host'      => '127.0.0.1',
        'database'  =>  $user->company,
        'username'  =>  'root',
        'password'  =>  '',
        'charset'   => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'strict'    => false,
        'options'   => [                                
            \PDO::ATTR_EMULATE_PREPARES => true
        ]
    ));

    return redirect()->intended($this->redirectPath());
}

Quelqu'un peut-il me dire pourquoi cela se produit? Que dois-je faire?


5 commentaires

Ce lien vous aidera à: stackoverflow.com/ questions / 31041893 /…


Ouais mais ça ne marche toujours pas


essayez celui-ci: stackoverflow.com / questions / 42280189 /…


Comme l'explique @ZaquPL dans sa réponse, quelle que soit la configuration que vous définissez ne sera bonne que pour la requête en cours, c'est-à-dire la requête où l'utilisateur se connecte et où authenticated () est appelé. Dès que votre redirect () se produit à la fin de cette méthode, cela génère une nouvelle requête, et la configuration par défaut est à nouveau chargée.


vous voulez utiliser plusieurs bases de données même connexion?


3 Réponses :


7
votes

Toutes les requêtes sont sans état donc la requête actuelle ne sait pas que vous avez défini une nouvelle valeur de configuration dans la requête précédente.

Vous devez appeler Config :: set (...) chaque fois que vous souhaitez utiliser une base de données dynamique et définir le nom de la base de données en obtenant cette valeur à partir de l'instance User .

La configuration ci-dessus doit être effectuée en utilisant middleware et service provider .

Créez un nouveau middleware et enregistrez-le pour le groupe middleware web (vous pouvez le faire en utilisant la propriété $ middlewareGroups de votre noyau HTTP):

session(['db_name' => $dbname]); // Set db_name and store it

$db_name = session('db_name'); // Get db_name from session

Ensuite :

<?php namespace App\Http\Middleware;

class YourMiddleware
{
    public function handle($request, Closure $next)
    {
        if (Auth::check()) {
            $database_name = Auth::user()->company;

            // Set your config here using $user->company
            // ...
        }

        return $next($request);
    }
}

Si vous devez définir cette valeur une fois (pendant l'authentification), vous devez combiner le code ci-dessus et les sessions pour stocker ces informations entre les requêtes:

protected $middlewareGroups = [
    'web' => [
        //...
        \App\Http\Middleware\YourMiddleware::class,
    ],
    //...
];

En savoir plus sur les sessions HTTP: ht tps: //laravel.com/docs/5.7/session#retrieving-data


1 commentaires

Bonne réponse, cependant j'ai 1 ajout. Afin de vous assurer que la bonne base de données est utilisée, appelez également DB :: reconnect ();



0
votes

Vous devez d'abord créer une nouvelle base de données par défaut pour la connexion et l'ajouter à database.php comme la connexion normale

   protected $table = 'stocks';  
   protected $connection = 'dynamicdb';

 /**
 * @return string
 */
public function getTable()
{
    $table = parent::getTable();
    $database = config('database.connections.dynamicdb.database');
    return starts_with($table, $database)
        ? $table
        : $database . '.' . parent::getTable();
}

/**
 * Set the table associated with the model.
 *
 * @param  string $table
 * @return $this
 */
public function setTable($table)
{
    $database = config('database.connections.dynamicdb.database');
    $this->table = starts_with($table, $database)
        ? $table
        : $database . '.' . $table;

    return $this;
}

suivant les méthodes de modèle de remplacement en stock

    'dynamicdb' => [
        'driver'      => 'mysql',
        'host'        => env('DB_HOST', '127.0.0.1'),
        'port'        => env('DB_PORT', '3306'),
        'database'    => 'default',
        //others
    ],

Utilisation: \ Config :: set ('database.connections.dynamicdb.database', $ user-> company); ou vous pouvez créer un assistant pour cela N'oubliez pas que cette méthode ne fonctionne qu'une seule connexion et que l'utilisateur connecté a accès à toutes les bases de données


0 commentaires

0
votes

Ajouter plusieurs bases de données dans .env

protected function stock_info() {
  return \DB::connection('alt_mysql')->select('*')->from('stocks')->get();
}

Modifier config/database.php[

protected $connection = 'alt_mysql';


1 commentaires

Pour chaque appel, nous pourrions avoir à appeler cela. C'est donc une solution, mais pas celle du préfet.