一个简单的 Laravel 站点设置实现

描述

站点少不了一些设置,例如站点设置、备案信息、统计代码等等。。。这些死的信息当然了单独新建一个文件放在config文件夹下面也没问题。但是有时候需要更改的时候却有些麻烦。例如网站已经上线了,想在后台控制面板设置网站的SEO关键字,更改备案信息如何办?毕竟config文件中直接修改起来不是很方便。

解决:把配置文件放入数据库或者文件夹中。

这里,我们来简单的实现一下 !
源码:https://github.com/codewithyou/laravel-common-settings

定义服务提供者

这里我们把这个功能叫做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://d.laravel-china.org/docs/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 ,有待完善。

比较简单,欢迎指点!!!