i want to use multiple databases, i have 1db/user and 1 main db,already set main db in config file but how to manage user database(db name = {user_id}_db). thanks in advance
this is my config code
'main' => [
'driver' => 'mysql',
'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', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
You can use following configuration for multiple dbs.
<?php
return array(
'default' => 'mysql',
'connections' => array(
# primary
'mysql' => array(
'driver' => 'mysql',
'host' => 'ip1',
'database' => 'db1',
'username' => 'user',
'password' => 'pwd'
'charset' => 'utf8',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
),
# secondary db connection
'mysql2' => array(
'driver' => 'mysql',
'host' => 'dbip2',
'database' => 'db2',
'username' => 'user',
'password' => 'pwd'
'charset' => 'utf8',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null
),
'sqlite' => array(
'driver' => 'sqlite',
'database' => __DIR__.'/../database/db.sqlite',
'prefix' => '',
),
),
);
Then you can use the the connection() method:
$connection = ‘mysql2’;
Schema::connection($connection)->create(function(Blueprint $table) {
//
});
Creating DB for each user is useless, even if you are doing it for security or any other purpose whatsoever. Useful SO link MySQL performance: multiple tables vs. index on single table and partitions
Your question (connecting to multiple databases in Laravel) is already answered here. How to use multiple database in Laravel
UPDATE
I guess, you want to create new databases on the fly and connect to them (without using .env configuration). Create dynamic connections instead of specifying 'connection-name' when trying to connect to a new database. Then, using Config::set you can create new temporary connections and then use DB::connection with the temporary name you just created. read more https://lukevers.com/2015/03/25/on-the-fly-database-connections-with-laravel-5
I'm moving the old project database to a new project database. the structure of the old project database is a single MYSQL database and the new project is the multi-tenant database which contained a lot of subdomains. Also, the new project already set up a RESTFUL API to receive the data from the old project. Therefore, my idea is to implement the multi-connection in the new project in order to link both databases together then get data from the old project. Example, the new project sales table is an empty and old project sales table already contains some data. Now in my new project interface maybe have a sync button in order to move data from the old database into a new database. Do I need to pass the API key before sending data into a new project? Since it's a multi-tenant structure.
This is my config/database
'mysql' => array(
'driver' => 'mysql',
'host' => 'aurora-2016-cluster.cluster-rtygfdfg.ap-southwest-1.rds.amazonaws.com',
'database' => 'newProject',
'username' => #$_ENV['DB_USER'] ?: '',
'password' => #$_ENV['DB_PASS'] ?: '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Our secondary database connection
'mysql2' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'oldProject',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
Its Quite Simple in laravel open your config/databse.php file
you will find the code like this
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'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', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
];
Steps to be followed
Step1:
Adding new arry to databse connection array
'mysqlSecondConnection' => [
'driver' => 'mysql',
'host' => env('DB_HOST1', '127.0.0.1'),
'port' => env('DB_PORT1', '3306'),
'database' => env('DB_DATABASE2', 'secondDatabseName'),
'username' => env('DB_USERNAME2', 'secondDatabseUserName'),
'password' => env('DB_PASSWORD2', 'secondDatabsePassword'),
'unix_socket' => env('DB_SOCKET2', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
After this your file may look like
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'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', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
],
'mysqlSecondConnection' => [
'driver' => 'mysql',
'host' => env('DB_HOST1', '127.0.0.1'),
'port' => env('DB_PORT1', '3306'),
'database' => env('DB_DATABASE2', 'secondDatabseName'),
'username' => env('DB_USERNAME2', 'secondDatabseUserName'),
'password' => env('DB_PASSWORD2', 'secondDatabsePassword'),
'unix_socket' => env('DB_SOCKET2', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
];
Step2: Configure Your Database name in mysqlSecondConnection array
IF THIS PROJECT IS TEAM COLLABRATING DONT FORGET TO ADD THE NEW ATTRIBUTES IN .ENV FILE
Step 3:
Now we are finished configuring the databse
Step 4:
Open you Model that need to interacts with the mysqlSecondConnection Database
And add the
Property
protected $connection ='mysqlSecondConnection';
After this the mode may look like For Eg:
I am Considering it as Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class Cat
*
* #package App
*/
class Post extends Model
{
/**
* The connection name for the model.
*
* #var string
*/
protected $connection ='mysqlSecondConnection';
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = ['id'];
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'posts';
/**
* The primary key for the model.
*
* #var string
*/
protected $primaryKey = 'id';
/**
* The "type" of the auto-incrementing ID.
*
* #var string
*/
protected $keyType = 'int';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name','title','desc'];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [];
/**
* #var array
*/
protected $dates = ['created_at','updated_at'];
}
Thats its
Now the testing part
Open your web.php file inside route folder
and paste the following code
Route::get('/testSecondConnection', function ()
{
$posts= App\Post::all();
dd($posts);
});
Now navigate to yourApplication/testSecondConnection
now see the connection property in the dumped
EDITED
I actually Forget to add another method that is via DB Facade version
Just pass the connection name to the DB inside the connection method
While using this this does not check for model
for the $connection Property in Post Model
$dbVersion = \DB::connection('mysqlSecondConnection')->table('posts')->get();
dd($dbVersion);
Edited for But which method is more efficient?
Good question Mate
Situation 1:
For Eg:
If You are Using the mysqlSecondConnection for the Post model in all the situation of your project then
add this to Your model
protected $connection ='mysqlSecondConnection';
and this is good and
NOTE $connection Property Will work on Eloquent not in DB Facade
Situation 2:
`Eg:'
if you are using only few Queries and calls to that mysqlSecondConnection
You Dont need to add
protected $connection ='mysqlSecondConnection';
Post Model
DB Facade Version
$dbVersion = \DB::connection('mysqlSecondConnection')->table('posts')->get();
dd($dbVersion);
Eloquent Version
$eloquentVersion = Post::on('mysqlSecondConnection')->get()
dd($eloquentVersion);
YOU MAY GET THE DOUBT WHY DB FACADE IS NOT USING mysqlSecondConnection IN POST MODEL
Solution:
While using the DB FACADE
It Will look into the config/datbase.php
for default array
Which is used in connection to database
'default' => env('DB_CONNECTION', 'mysql'),
Hope its helps and look clear
The names of DB are board 1, board 2, board 3, board 4 to board 50. It takes time to create multiple connections each time, and I will have to do manual work every time I add it.
There is no solution for getting an error if you like the existing method in database.php?
for($board_no=1;$board_no<=50;$board_no++){
'board'.$board_no => [
'driver' => 'mysql',
'host' => 'boardip',
'port' => '3306',
'database' => 'board'.$board_no,
'username' => 'boardadmin',
'password' => 'boardadminpassword',
'unix_socket' => '',
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => null,
'engine' => null
],
}
To create a config on the fly:
Do this in your controller, it would just be appended to "database.connections" config.
Config::set('database.connections.key', array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'dbname',
'username' => 'dbuser',
'password' => 'dbpass',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
));
Then you can connect to the db using:
DB::connection('key');
I have main database with some tables and for every client we have different databases.While using events and listeners where do I specify the connection string to use.For model and controller I have used Config:set to change my connection string dynamically for one request.I added the same in the listeners handle method,but that isn't working and the events shows as failed.
Thanks in advance.
The Listener method.
public function handle(ApplicationAssociated $event)
{
echo "Hi";
$client_id=$event->client_id;
echo 'hiii'.$client_id;
$dbconnections=DBConnection::where('client_id',$client_id)->get();
if($client_id>0)
{
foreach($dbconnections as $dbconnection)
{
echo "in if the db name is".$dbconnection->mysql_database;
echo "break";
if($dbconnection->mysql_password==NULL)
{
$password="";
}
else
{
$password=$dbconnection->password;
}
\Config::set([
'database.connections.mysql1.host' => $dbconnection->mysql_host,
'database.connections.mysql1.database' => $dbconnection->mysql_database,
'database.connections.mysql1.username' => $dbconnection->mysql_username,
'database.connections.mysql1.password' => $password,
]);
}
}
echo \Config::get('database.connections.mysql1.database');
Application::where('id',21)
->update(['name' =>'Testing eventing']);
echo "LAST";
}
try this out.
config/database.php
'mysql2' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE2', 'forge'),
'username' => env('DB_USERNAME2', 'forge'),
'password' => env('DB_PASSWORD2', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
.env file
DB_DATABASE2=ichuztowork
DB_USERNAME2=root
DB_PASSWORD2=
Anywhere in your application you can set the connection string in this way
$user = (new \App\User(['name'=>'My Name', 'email'=>'myEmail#email.com']))-
>setConnection('foreignDB');
$user->save();
// or if you don't need to use the model, then just
(new \App\User(['name'=>'My Name', 'email'=>'myEmail#email.com']))-
>setConnection('foreignDB')->save();
(Laravel Config::set Persist Through Requests?)
After getting the answer below, I tried it out...
'default' => 'mysql_main',
'connections' => [
'mysql_main' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
'mysql_company' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => Auth::user()->club->db_name,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
],
However, upon doing this inside the database.php folder under config I receive the following error...
Fatal error: Class 'Auth' not found in F:\trapstats_v5\config\database.php on line 73.
Is there another way to do dynamic database connections, based on the user, that will save through requests instead of doing config([database.connections.mysql_company.database' => Auth::user()->club->db_name]) every time I want to access the dynamic connection?
This question is similar to the answer of Dynamic database connection in Laravel. And if I do this answer as well I get the same sort of error except this time it is called Session instead of Auth.
In your config files doing
'database' => Auth::user()->club->db_name,
Is dangerous because Auth is probably not setup at the point your configuration files are read by Laravel, it needs your configuration files to lots of other things, so it should read them fist. What you can do, in, lets say a ServiceProvider, or some other helper class is to:
config('database.connections.mysql_company', ['database' => Auth::user()->club->db_name]);
After doing some more reading and going around and asking many questions I have come up with a solution.
What I ended up doing was creating a middleware called Database that ran AFTER every other middleware finished. This allowed for use of all of the typical Laravel services (like Auth::user());
Database
class Database
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (!Auth::guest()) {
config(['database.connections.club.database' => Auth::user()->club->db_name]);
}
return $next($request);
}
}
And then for the route group I assign this middleware to it.