大多数时候我都总是希望将配置存入数据库里,虽然 laravel 可以很方便的通过config()函数读到自定义的配置,但通常情况下,这些配置都是通过修改/config目录下的相关文件实现的,不方便灵活管理。

所以我们对于从数据库读取配置信息有刚性需要,下面我就分享个人的解决方案。

一、数据库表信息:
首先,我们需要根据自己的情况建存放配置信息的表,下面是我的数据表参考:

CREATE TABLE `settings` (
  `key` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '变量名',
  `value` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '变量值',
  `note` varchar(64) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '参数说明',
  PRIMARY KEY (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统设置';

二、建立Model文件:

快捷操作,请使用下面的命令:

php artisan make:model Setting

也可以手工新建文件/app/Models/Setting.php,内容如下:

<?php

namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Setting extends Model
{
    public $timestamps = false; //不维护时间
    //protected $primaryKey = 'key'; //设置主键后,会被自动编号
    protected $fillable = ['key', 'value', 'note']; //可批量填充的字段

}

三、读配置到缓存

开始我想使用 app/Providers/AppServiceProvider.php 里的boot()实现程序运行就读取所需要的缓存,代码也比较繁琐,通常会借用的自己定义的辅助函数库。

绕了一圈,发现都用到了辅助函数了,为何不绕过 app/Providers/AppServiceProvider.php 文件,并按需要读取呢。所以我们需要直接在辅助函数库:app/helpers.php 里写入下面的代码即可:

if (!function_exists('settings')) {
    /**
     * 说明: 通过$key 从缓存/数据表settings返回配置值
     * @param mixed: $key 配置项键(可传多个键)
     * @return mixed: 自定的设置(数组)项
     */
    function settings($key)
    {
        static $settings; //静态变量 将$settings常驻内存
        if (is_null($settings)) {
            $settings =  Cache()->rememberForever('settings', function () {
                return Arr::pluck(Setting::all('key', 'value')->toArray(), 'value', 'key');
            });
        }
        //$key 传数组则返回多个 key->value
        return (is_array($key)) ? Arr::only($settings, $key) : $settings[$key];
    }
}
//注:Arr::* 为Laravel提供的辅助函数,功能及使用请自行查看官方文档

四、按需读取配置

例如:我们需要读取文章缓存时间:

$duration = settings('cache_time_article'); //文章缓存时间

同时可读取多个缓存项:

$configs = settings(['cache_time_article','cache_time_default','cache_time_category']); //多个缓存时间

在模板里读取配置:

@section('title', settings('seo_title'))
@section('keywords', settings('seo_keywords'))
@section('description',settings('seo_description'))