Reputation: 290
I am creating a SAAS application with a single laravel installation and multi tenant database. So i have a main DB that is connected to laravel by default. the client can access the application through their sub-domain like: client1.example.com and client2.example.com
I am saving all info fo the client like domain and db name in the main db.
How can change the DB according to the subdomain
I tried with the following Code
in routes/web.php
Route::group(['domain' => '{account}'], function() {
Route::get('/', function($account) {
// This will return {account}, which you can pass along to what you'd like
return $account;
});
});
in app/Providers\RouteServiceProvieder.php
public function boot(Router $router)
{
parent::boot($router);
$router->bind('domain', function ($value) {
//$hst=$request->getHost();
$domain= Customer::where('sub_domain',$value)->first();
if ($domain) {
return $domain;
}
throw new Exception('error message');
});
}
Then i have created a ServiceProvider ConfigServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Request;
class ConfigServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register(Request $request)
{
$customer=$request->route('domain');
//$customer = Request::route('domain'); // there are multiple ways of doing this
//$customer = $request->route()->domain;
config([
'database.mysql.database' => $customer->customer_database, //this is because I have same username and password for all the databases. If you have different username and passwords set them too.
]);
DB::reconnect(); // this will help in reconnecting the database if the connection is already established. and import the DB facade.
}
}
But the code is not working?
The Error i am getting is
FatalThrowableError in ConfigServiceProvider.php line 25:
Type error: Too few arguments to function App\Providers\ConfigServiceProvider::register(), 0 passed in C:\xampp\htdocs\main\vendor\laravel\framework\src\Illuminate\Foundation\Application.php on line 568 and exactly 1 expected
I am using Laravel 5.4. Can any one guide me how to do it correctly?
Upvotes: 1
Views: 3219
Reputation: 40663
What I would suggest is to create 2 .env
files, one for each subdomain e.g. .env.domain1
and .env.domain2
Then in your app service provider:
public function boot() { //Use boot for this
$fn = ".env.".$this->app->request->route('domain');
$dotenv = new \Dotenv\Dotenv(self::basePath(), $fn);
try {
$dotenv->overload();
} catch (\Dotenv\Exception\InvalidPathException $e) {
//Nothing to overload with
}
}
This makes your sub-domains behave like different environments which does look like what you're trying to do.
Upvotes: 2
Reputation: 9161
well there are some issues here:
First the register() method of a service provider should not accept a Request instance as argument. Its better to write it like that:
public function register()
Second, dont use config() in the register() method, from the laravel docs:
within the register method, you should only bind things into the service container. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register method. Otherwise, you may accidentally use a service that is provided by a service provider which has not loaded yet.
IMHO I would use a middleware to change the database configuration like you tried in a service provider, i.e:
public function handle($request, Closure $next)
{
$customer=$request->route('domain');
if($customer)
{
config(['database.mysql.database' => $customer->customer_database]);
DB::reconnect();
}
return $next($request);
}
If you take care of loading the middleware in the right place (look in app/Http/Kernel.php) you will have database changed before any query.
Upvotes: 4
Reputation: 7371
Change
use Illuminate\Support\Facades\Request;
to
use Illuminate\Http\Request;
You can not use Facades for dependency/method injection. Hope it helps
Upvotes: 1