Laravel - 从设置表

时间:2015-12-07 04:41:55

标签: php laravel laravel-5.1

我正在尝试将我的settings表格中的所有设置存储到全局变量中,但我现在陷入困境(我不知道下一步是什么),这是我的实际模型和播种机:

model - Settings.php

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

    public $timestamps = false;

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

播种机 - 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);
        }
    }
}

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

修改

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

我已经设置了这个:

我的路线:

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

我的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');
    }
}

我的设置存储库:

class SettingRepository
{
    private $model;

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

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

我的刀片形式:

{!! 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() !!}

但是事情不起作用。如何将值更新到表中?

4 个答案:

答案 0 :(得分:23)

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

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

config('settings.facebook');

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

您可以使用工匠创建服务提供商:

php artisan make:provider SettingsServiceProvider

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

第2步:将其添加到您刚刚创建的提供程序的boot-method中:

/**
 * 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());
}

来自Laravel文档:

  

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

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

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

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

App\Providers\SettingsServiceProvider::class,

就是这样。快乐的编码!

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

更新2:作为Jeemusu mentioned in his comment,应用会在每次请求时查询数据库。为了阻止这种情况,您可以缓存设置。基本上有两种方法可以做到。

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

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

  3. 为了使思考更容错,我使用第二个选项。缓存可以无意中清除。只要管理员未设置设置或在服务器崩溃后重新安装,第一个选项将在全新安装时失败。

    对于第二个选项,请更改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);
    }
    

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

    /**
     * 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);
    }
    

答案 1 :(得分:3)

为避免在每次请求时查询数据库,每次admin / user更改时,都应将设置保存到配置文件中。

exclude 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.properties'
exclude 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.properties'
exclude 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.xml'
exclude 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.xml'

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

    // 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);

Laravel将自动包含<?php return array( name => 'value', name => 'value', ); 目录中的任何php文件以及应用程序可通过/config帮助程序访问的数组变量:

config()

答案 2 :(得分:0)

您可以将数据存储在数据库中,就像在Laravel中一样。 \App\Setting::create()\App\Setting::new()和其他方法。

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

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

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

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

答案 3 :(得分:0)

我想分享我的用例,我的回答可能不是直接回答OP,而是希望回答未来的开发者。

这已在 Laravel 8 应用程序中进行了测试,但我相信它可以在 Laravel 5.5 及更高版本中正常工作。

就我而言,我有一个包含 keyvalue 字段的设置表,如您在此迁移文件中所见。

<?php

use...;

class CreateSettingsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('settings', function (Blueprint $table) {
            $table->id();
            $table->string('key')->unique();
            $table->text('value');
            $table->timestamps();
        });
    }

    //...
}

我在应用程序中大量使用存储在此表中的值,因此为了提高性能,我将这些键/值存储在配置文件中,只要管理员在后台更新了值,我就会这样做。

为此,我使用 Eloquent 模型 events,更准确地说,我使用 saved 事件,因为 saving/saved 事件将在创建模型时分派或更新。

<?php

namespace App\Models;

use...;

class Setting extends Model
{
    use HasFactory;

    //...

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::saved(function () {

            $settings           = static::pluck('value', 'key')->toArray();

            $stringify_settings = var_export($settings, true);

            $content            = "<?php return {$stringify_settings};";

            File::put(config_path('app_settings.php'), $content);
        });
    }
}

我又做了一件事,我将 /config/app_settings.php 添加到 .gitignore 文件中。