一個簡單的 Laravel 站點設定實現

codewithyou發表於2017-10-04

站點少不了一些設定,例如站點設定、備案資訊、統計程式碼等等。。。這些死的資訊當然了單獨新建一個檔案放在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://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這個抽象類(也可以用介面實現)中來定義了,當然,也可以增加其他方法,但是目前我覺得夠用了。

<?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一定要唯一。

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 ,有待完善。

比較簡單,歡迎指點!!!

相關文章