一个简单的 Laravel 站点设置实现
描述
站点少不了一些设置,例如站点设置、备案信息、统计代码等等。。。这些死的信息当然了单独新建一个文件放在config文件夹下面也没问题。但是有时候需要更改的时候却有些麻烦。例如网站已经上线了,想在后台控制面板设置网站的SEO关键字,更改备案信息如何办?毕竟config文件中直接修改起来不是很方便。
解决:把配置文件放入数据库或者文件夹中。
这里,我们来简单的实现一下 !
源码:https://github.com/codewithyou/laravel-com...
定义服务提供者
这里我们把这个功能叫做settings服务,方便自己和别人使用。在App\Providers 下面新建provider文件,代码如下
<?php
namespace App\Providers;
use Exception;
use App\Models\Setting;
use App\Services\SettingsService;
use Illuminate\Support\ServiceProvider;
class SettingsServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
try {
$defaultSettings = $this->app->config->get('settings');
$settingInDisk = $this->app->settings->all();
$newSettings = array_merge($defaultSettings,$settingInDisk);
$this->app->config->set('settings',$newSettings);
}catch (Exception $e) {
//TODO collect logs.
}
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->singleton('settings',function () {
return new SettingsService(new Setting());
});
$this->app->alias('settings', SettingsService::class);
}
}
可以看见,在register中新建了一个settings单例,并起了别名。下面一步一步的从上往下讲解。
新建服务
<?php
/**
* Created by PhpStorm.
* User: andy
* Date: 2017/10/4
* Time: 上午10:24
*/
namespace App\Services;
use App\Contracts\SettingsContract;
use App\Models\Setting;
class SettingsService extends SettingsContract
{
protected $setting;
function __construct(Setting $setting)
{
$this->setting = $setting;
}
function all()
{
return $this->setting->all(['key', 'value'])->pluck('value', 'key')->toArray();//https://learnku.com/docs/laravel/5.5/collections#method-pluck
}
function set($key, $value) {
$this->isRefresh = true;
if ($value === null) {
$this->setting->where('key', $key)->delete();
} else {
$this->setting->updateOrCreate(compact('key'), compact('value'));
}
parent::set( $key , $value );
}
function delete($key) {
$this->isRefresh = true;
$this->setting->where('key', $key)->delete();
parent::delete($key);
}
}
这里主要的功能是对外界暴露settings主要有哪些功能。这里的功能在SettingsContract这个抽象类(也可以用接口实现)中来定义了,当然,也可以增加其他方法,但是目前我觉得够用了。
定义settings的数据库实现方式
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
protected $fillable = ['key', 'value'];
}
由于使用了Eloquent ORM所以,数据写起来很简单,毕竟我们只是简单的保存和查询。这样就够了!
添加数据库迁移文件
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('key')->unique();
$table->longText('value');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('settings');
}
}
这里,key一定要唯一。
添加provider
app.php配置文件中添加如下
App\Providers\SettingsServiceProvider::class,
这样 基本就可以用了!!!
看一下如何使用
安装之后
- 你可以在config下面的settings设置自己的配置;
- 可以在程序中调用接口$app->setting->set(key,value)设置一个key-value对
- 可以调用$app->config->get('settings.your-key') 获取设置的值
- 可以使用$app->settings->delete('your-key');删除一个pair
TODO
其他还有几个TODO ,有待完善。
比较简单,欢迎指点!!!
本作品采用《CC 协议》,转载必须注明作者和本文链接
我认为这类内容,因为改变的频率不大,可以在改变之后以 Array 或 JSON 的形式存储起来。再读起来只需要加载这份数据就好了,而不用每次都读数据库。
另外既然 key 字段设置为唯一的,那么是否还有必要加多一个id呢?
@IceBay 多谢指点 :sunglasses: id是可以去除的,生成migration文件自动生产了 。
对于频率不高的放入json也可以的,存储为文件。TODO里面也说了,也可以添加另外一个driver,文件存储!哈哈
可以在程序中调用接口 $app->setting->set (key,value) 设置一个 key-value 对
控制器里面应该怎么写呢?