Laravel dynamic config settings

2019-02-02 05:34发布

I'm using a package within my project and it stores a setting inside config/packagename

I would like to dynamically change this value inside the config file, this is how the file structure looks currently;

<?php

return [
    'view_id' => '118754561',

    'cache_lifetime_in_minutes' => 60 * 24,
];

I would like to change it to something like this -

'view_id' => Auth::user()->id,

Can you do this within the config file, or do you have to store some sort of variable to be updated later within a controller. Is there a way to place these variables in an env file and access these new variables from a controller?

8条回答
看我几分像从前
2楼-- · 2019-02-02 05:52

You can do like this.

In your custom config file. Add the following code You can send your id dynamically from the query string.

'view_id' => isset($_REQUEST['view_id'])?$_REQUEST['view_id']:null,

To get view id

 echo config('app.view_id'); // app is config file name
查看更多
倾城 Initia
3楼-- · 2019-02-02 05:54

config(['packagename.view_id' => Auth::user()->id]);

查看更多
干净又极端
4楼-- · 2019-02-02 05:56

Use this in controller when you need to change.

  <?php

    use Illuminate\Support\Facades\Config;

     //[...]

    $user_id =  Auth::user()->id; 

    Config::set('view_id', $user_id );
查看更多
兄弟一词,经得起流年.
5楼-- · 2019-02-02 05:56

Since Laravel v5.2 you can dynamically set config values this way:

<?php

config(['app.timezone' => 'America/Chicago']);

$value = config('app.timezone');

echo $value;
// output: 'America/Chicago'
查看更多
贪生不怕死
6楼-- · 2019-02-02 06:00

If you want to actually edit the config files (either config/packagename.php or .env) then you may follow matthiku's answer.

However, if I were you, I guess I'd rather want to configure this 3rd party package based on some value defined at runtime, instead of modifying any file (which by the way won't take effect until the next request, when the env values are read again).

So, in my opinion the cleanest way to do this is:

  • store your desired value in the config data:

    config(['packagename.view_id' => Auth::user()->id]);

  • However, you may notice this probably won't work: the service provider which provides the service you need is often registered before the request is processed, that is, before your config change takes place. So you are still getting the service with old values config.

  • So, how could you have the service provider be called only when needed and not before (that is, after setting the new config value)? You could make it a deferred provider. Following your example of "spatie laravel-analytics", replace in config/app.php this line:

    Spatie\Analytics\AnalyticsServiceProvider::class

    with this one:

    App\Providers\AnalyticsDeferredServiceProvider::class

    and finally create the App\Providers\AnalyticsDeferredServiceProvider class, with:

:

<?php
namespace App\Providers;

use Spatie\Analytics\Analytics;
use Spatie\Analytics\AnalyticsServiceProvider;

class AnalyticsDeferredServiceProvider extends AnalyticsServiceProvider
{
    protected $defer = true;

    public function provides()
    {
        return [Analytics::class];
    }
}

This way you can have the provider read the config values when you are about to instantiate the service, after you set any runtime config values.

查看更多
祖国的老花朵
7楼-- · 2019-02-02 06:09

This also is a generic solution to dynamically update your .env file (respective the individual key/value pairs)

  1. Change the setting in your config/packagename like so:
return [
    'view_id' => env('VIEW_ID', '118754561'),
    etc...
]
  1. Add an initial value into .env:

    VIEW_ID=118754561

  2. In an appropriate controller (e.g. AuthController), use the code below and call the function like this: updateDotEnv('VIEW_ID', Auth::User()->id)

    protected function updateDotEnv($key, $newValue, $delim='')
    {
    
        $path = base_path('.env');
        // get old value from current env
        $oldValue = env($key);
    
        // was there any change?
        if ($oldValue === $newValue) {
            return;
        }
    
        // rewrite file content with changed data
        if (file_exists($path)) {
            // replace current value with new value 
            file_put_contents(
                $path, str_replace(
                    $key.'='.$delim.$oldValue.$delim, 
                    $key.'='.$delim.$newValue.$delim, 
                    file_get_contents($path)
                )
            );
        }
    }
    

(The $delim parameter is needed if you want to make this function more generic in order to work with key=value pairs in .env where the value has to be enclosed in double quotes because they contain spaces).

Admittedly, this might not be a good solution if you have multiple users at the same time using this package in your project. So it depends on what you are using this package for.

NB: You need to make the function public of course if you plan to use it from other classes.

查看更多
登录 后发表回答