Простой способ хранить настройки приложения Yii2 в БД

Редактируемые параметры yii2-приложения в админке, которые легко получить в любом месте приложения, например, название или краткое описание (привет, вордпресс 😁) нашего сайта в views layouts:

<?= Yii::$app->config->siteName ?>

MySQL Schema

CREATE TABLE IF NOT EXISTS `config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `val` varchar(255) DEFAULT NULL,
  `label` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

В большинстве случаев я использую yii2-app-basic, поэтому пример для этого шаблона.

Генерируем модель в Gii.
Привожу attributeLabels, ну и заодно пояснения:

    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Параметр', // Уникальное имя параметра для кодера
            'val' => 'Значение', // Размер значения можно увеличить
            'label' => 'Название' // Человекопонятное названия для админа/контент-менеджера
        ];
    }

Возможно, это странно, но пока не приходилось использовать слишком объемные «параметры» и было достаточно всего лишь VARCHAR(255) для значений (val), можете смело использовать TEXT, в WP, откуда частично позаимствована идея такого конфига, используется LONGTEXT (OMG!) в ущерб большей универсальности, чем производительности (у нас упор на максимум её). Я не рекомендую хранить слишком большой конфиг таким способом!

CRUD’им получившуюся модель Config в том же Gii по своему вкусу.

Создаем такой простой компонент components/Config.php:

<?php

namespace app\components;

use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;

class Config extends Component {

    private $_attributes;

    /**
     * @inheritdoc
     */
    public function init() {
        parent::init();
        $this->_attributes = ArrayHelper::map(\app\models\Config::find()->all(), 'name', 'val');
    }

    public function __get($name) {
        if (array_key_exists($name, $this->_attributes))
            return $this->_attributes[$name];

        return parent::__get($name);
    }
}

Далее правим конфиг yii-2 приложения (config/web.php), добавляем наш компонент:

$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log', 'config'], // добавляем наш компонент в автозагрузку
'components' => [
...
        'config' => [ // сам компонент прописываем
            'class' => 'app\components\Config',
        ],
    ],

Готово!

Небольшой совет (как в том же самом wp_options), если вы все-таки решились хранить очень объемные параметры/данные таким образом, то можно добавить в БД/модель BOOL флаг autoload и подгружать только реально используемые при каждом запросе параметры в components/Config.php.

$this->_attributes = ArrayHelper::map(\app\models\Config::find(['autoload' => true])->all(), 'name', 'val');