我正在尝试将我的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() !!}
但是事情不起作用。如何将值更新到表中?
答案 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,应用会在每次请求时查询数据库。为了阻止这种情况,您可以缓存设置。基本上有两种方法可以做到。
每次管理员更新时,都会将数据放入缓存中 设置。
只需记住缓存中的设置一段时间,并在每次管理员更新设置时清除缓存。
为了使思考更容错,我使用第二个选项。缓存可以无意中清除。只要管理员未设置设置或在服务器崩溃后重新安装,第一个选项将在全新安装时失败。
对于第二个选项,请更改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 及更高版本中正常工作。
就我而言,我有一个包含 key 和 value 字段的设置表,如您在此迁移文件中所见。
<?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
文件中。