Laravel - 从设置表中设置全局变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34126578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:46:55  来源:igfitidea点击:

Laravel - Set global variable from settings table

phplaravellaravel-5.1

提问by Caio Kawasaki

I'm trying to store all my settings from my settingstable into a global variable, but I'm stucked now(I have no idea what's the next step), this is my actual model and seeder:

我试图将我的settings表中的所有设置存储到一个全局变量中,但我现在被卡住了(我不知道下一步是什么),这是我的实际模型和播种机:

model - Settings.php

模型 - Settings.php

class Setting extends Model
{
    protected $table = 'settings';

    public $timestamps = false;

    protected $fillable = [
        'name',
        'value',
    ];
}

seeder - SettingsTableSeeder.php

播种机 - SettingsTableSeeder.php

class SettingsTableSeeder extends Seeder
{
    public function run()
    {

        $settings = [
            ['name' => 'title', 'value' => ''],
            ['name' => 'facebook', 'value' => ''],
            ['name' => 'twitter', 'value' => ''],
            ['name' => 'instagram', 'value' => '']
        ];

        foreach($settings as $setting){
            \App\Setting::create($setting);
        }
    }
}

How can I store all the data inside the settings table and make then acessible from blade, or any controller or view?

如何将所有数据存储在设置表中,然后从刀片、任何控制器或视图访问?

Edit

编辑



Now, my question is, how can i update a single or multiple value(s) from a form?

现在,我的问题是,如何从表单更新单个或多个值?

I have set this up:

我已经设置了这个:

My route:

我的路线:

Route::put('/', ['as' => 'setting.update', 'uses' => 'Admin\AdminConfiguracoesController@update']);

My Admin\AdminConfiguracoesController:

我的 Admin\AdminConfiguracoesController:

class AdminConfiguracoesController extends AdminBaseController
{
    private $repository;

    public function __construct(SettingRepository $repository){
        $this->repository = $repository;
    }

    public function geral()
    {
        return view('admin.pages.admin.configuracoes.geral.index');
    }

    public function social()
    {
        return view('admin.pages.admin.configuracoes.social.index');
    }

    public function analytics()
    {
        return view('admin.pages.admin.configuracoes.analytics.index');
    }

    public function update($id, Factory $cache, Setting $setting)
    {
        $this->repository->findByName($setting);

        $cache->forget('settings');

        return redirect('admin');
    }
}

My SettingRepository:

我的设置存储库:

class SettingRepository
{
    private $model;

    public function __construct(Setting $model)
    {
        $this->model = $model;
    }

    public function findByName($name){
        return $this->model->where('name', $name)->update();
    }
}

My blade form:

我的刀片形式:

{!! Form::model(config('settings'), ['class' => 's-form', 'route' => ['setting.update']]) !!}
{{ method_field('PUT') }}
<div class="s-form-item text">
    <div class="item-title required">Título do artigo</div>
    {!! Form::text('title', null, ['placeholder' => 'Nome do site']) !!}
    @if($errors->has('title'))
        <div class="item-desc">{{ $errors->first('title') }}</div>
    @endif
</div>
<div class="s-form-item s-btn-group s-btns-right">
    <a href="{{ url('admin') }}" class="s-btn cancel">Voltar</a>
    <input class="s-btn" type="submit" value="Atualizar">
</div>
{!! Form::close() !!}

But things does not work. How can I update the values into the table?

但事情并不奏效。如何将值更新到表中?

回答by tommy

See improved answer in Update 2

请参阅更新 2 中的改进答案

I would add a dedicated Service Provider for this. It will read all your settings stored in the database and add them to Laravels config. This way there is only one database request for the settings and you can access the configuration in all controllers and views like this:

我会为此添加一个专门的服务提供商。它将读取存储在数据库中的所有设置并将它们添加到 Laravel 配置中。这样,设置只有一个数据库请求,您可以访问所有控制器和视图中的配置,如下所示:

config('settings.facebook');

Step 1: Create the Service Provider.

第 1 步:创建服务提供者。

You can create the Service Provider with artisan:

您可以使用 artisan 创建服务提供者:

php artisan make:provider SettingsServiceProvider

php artisan make:provider SettingsServiceProvider

This will create the file app/Providers/SettingsServiceProvider.php.

这将创建文件app/Providers/SettingsServiceProvider.php

Step 2: Add this to the boot-method of the provider you have just created:

第 2 步:将其添加到您刚刚创建的提供程序的引导方法中:

/**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{
    // Laravel >= 5.2, use 'lists' instead of 'pluck' for Laravel <= 5.1
    config()->set('settings', \App\Setting::pluck('value', 'name')->all());
}

From the Laravel Docs:

来自 Laravel 文档:

[The boot method] is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework.

[引导方法] 在所有其他服务提供者注册后调用,这意味着您可以访问框架注册的所有其他服务。

http://laravel.com/docs/5.1/providers#the-boot-method

http://laravel.com/docs/5.1/providers#the-boot-method

Step 3: Register the provider in your App.

第 3 步:在您的应用程序中注册提供程序。

Add this line to the providersarray in config/app.php:

将此行添加到providers数组中config/app.php

App\Providers\SettingsServiceProvider::class,

And that's it. Happy coding!

就是这样。快乐编码!

Update:I want to add that the boot-method supports dependency injection. So instead of hard coding \App\Setting, you could inject a repository / an interface that is bound to the repository, which is great for testing.

更新:我想补充一点,引导方法支持依赖注入。因此\App\Setting,您可以注入存储库/绑定到存储库的接口,而不是硬编码,这非常适合测试。

Update 2:As Jeemusu mentioned in his comment, the app will query the database on every request. In order to hinder that, you can cache the settings. There are basically two ways you can do that.

更新 2:正如Jeemusu 在他的评论中提到的,应用程序将在每次请求时查询数据库。为了阻止这种情况,您可以缓存设置。基本上有两种方法可以做到这一点。

  1. Put the data into the cache every time the admin is updating the settings.

  2. Just remember the settings in the cache for some time and clear the cache every time the admin updates the settings.

  1. 每次管理员更新设置时都将数据放入缓存中。

  2. 只需记住缓存中的设置一段时间,并在管理员每次更新设置时清除缓存。

To make thinks more fault tolerant, I'd use the second option. Caches can be cleared unintentionally. The first option will fail on fresh installations as long as the admin did not set the settings or you reinstall after a server crash.

为了使思考更具容错性,我将使用第二个选项。缓存可能会被无意清除。只要管理员没有设置设置或者您在服务器崩溃后重新安装,第一个选项就会在全新安装时失败。

For the second option, change the Service Providers boot-method:

对于第二个选项,更改 Service Providers 启动方法:

/**
 * Bootstrap the application services.
 *
 * @param \Illuminate\Contracts\Cache\Factory $cache
 * @param \App\Setting                        $settings
 * 
 * @return void
 */
public function boot(Factory $cache, Setting $settings)
{
    $settings = $cache->remember('settings', 60, function() use ($settings)
    {
        // Laravel >= 5.2, use 'lists' instead of 'pluck' for Laravel <= 5.1
        return $settings->pluck('value', 'name')->all();
    });

    config()->set('settings', $settings);
}

Now you only have to make the cache forget the settings key after the admin updates the settings:

现在你只需要在管理员更新设置后让缓存忘记设置键:

/**
 * Updates the settings.
 *
 * @param int                                 $id
 * @param \Illuminate\Contracts\Cache\Factory $cache
 *
 * @return \Illuminate\Http\RedirectResponse
 */
public function update($id, Factory $cache)
{
    // ...

    // When the settings have been updated, clear the cache for the key 'settings':
    $cache->forget('settings');

    // E.g., redirect back to the settings index page with a success flash message
    return redirect()->route('admin.settings.index')
        ->with('updated', true);
}

回答by Jeemusu

To avoid querying the database on each request, you should save the settings to a config file each time they are changed by the admin/user.

为了避免每次请求都查询数据库,您应该在管理员/用户每次更改设置时将设置保存到配置文件中。

    // Grab settings from database as a list
    $settings = \App\Setting::lists('value', 'name')->all();

    // Generate and save config file
    $filePath = config_path() . '/settings.php';
    $content = '<?php return ' . var_export($settings, true) . ';';
    File::put($filePath, $content);

The above will create a Laraval compatible config file that essentially just returns an array of key => values. The generated file will look something like this.

上面将创建一个 Laraval 兼容的配置文件,它基本上只返回一个键 => 值的数组。生成的文件看起来像这样。

<?php 

return array(
    name => 'value',
    name => 'value',
);

Any php file in the /configdirectory will be auto-included by Laravel and the array variables accessible to your application via the config()helper:

/config目录中的任何 php 文件都将被 Laravel 自动包含,并且您的应用程序可以通过config()帮助程序访问数组变量:

config('settings.variable_name');

回答by Curos

You can store the data in the database just like you do it normally in Laravel. \App\Setting::create(), \App\Setting::new()and other methods.

您可以像在 Laravel 中通常那样将数据存储在数据库中。\App\Setting::create()\App\Setting::new()以及其他方法。

For using the values in blade, you can do {{\App\Setting::where('name','title')->pluck('value')}}

要使用刀片中的值,您可以执行 {{\App\Setting::where('name','title')->pluck('value')}}

And, you can also use scopes for this.

而且,您也可以为此使用范围。

class Setting extends Model
{
    public function scopeFor($query, $settingName)
    {
        return $query->where('name', $settingName);
    }
}

then you could use \App\Setting::for('title')->pluck('value')

那么你可以使用 \App\Setting::for('title')->pluck('value')