Laravel Config::set Persist Through Requests?

前端 未结 2 1793
名媛妹妹
名媛妹妹 2021-01-23 00:03

I have been building a web application that tracks statistics. These statistics can range between different companies.
I decided to use a main database to house all of the l

相关标签:
2条回答
  • 2021-01-23 00:20

    Well, you can't actually use config for this.

    Configuration values that are set at run-time are only set for the current request, and will not be carried over to subsequent requests.

    Laravel documentation reference.

    Workaround

    As a hacky workaround, and if you are not willing to use your main database to store the company database connection data, you could use a custom configuration file that you could update on run-time.

    This is very similar to how the original config file works and it should keep the data persistently. However you have to build a control mechanism around it to keep the entries unique and consistent:

    Update Config on Runtime Persistently

    You could also look for a package for this so you dont have to re-invent the wheel. Check laravel-config-writer (disclaimer: never personally used it).

    0 讨论(0)
  • 2021-01-23 00:32

    After OP's request, I submit a second answer as a different approach.

    If this is only intented for database connection details, you could use the following approach with multiple database connections in a single Laravel application.

    In app/config/database.php you define two different connections. One for your main database where your users table is stored and one dynamic for the per-client instance:

    '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' => Auth::user()->club->db_user,
            'password' => Auth::user()->club->db_pass,
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
    
    ],
    

    As you can see you dont actually need to read the connection details of the second connection from the config file (it would still be used to get host, port and any common details with your main database), you can pass the different connection details dynamically from your logged-in user. However this will require you to have created all the databases for every user in advance.

    After you have managed to connect to both databases, you will have to select the active connection anytime you execute a query.

    Hopefully Schema Builder, Query Builder and Eloquent support this out of the box:

    Shema Builder

    Schema::connection('mysql_company')->create('statisticA', function($table)
    {
        $table->increments('id'):
    });
    

    Query Builder

    $companyStatA = DB::connection('mysql_company')->select(...);
    

    Eloquent Model

    class StatisticA extends Eloquent {
    
        protected $connection = 'mysql_company';
    
    }
    

    Controller

    class SomeController extends BaseController {
    
        public function someMethod()
        {
            $statA = new StatisticA;
    
            $statA->setConnection('mysql_company');
    
            $something = $statA->find(1);
    
            return $something;
        }
    
    }
    

    However what would be tricky is to define relationships between models stored in different databases. It is be possible but it strongly depends on your database driver and settings.

    I doubt it would function correctly between different types of databases (eg MySQL as your main database and PostgreSQL for you company databases), so I'd suggest you to stick with MySQL and see how this goes.

    0 讨论(0)
提交回复
热议问题