MySQL версии 5.7 получил новый тип данных JSON и набор SQL функций для работы с ним. Хотя и до этого можно было использовать данный формат хранения данных создавая текстовое поле в таблице базы данных. Таким образом еще актуальнее стал вопрос использования данного формата совместно с БД.

В WEB-приложении мы оперируем массивами и объектами, которые необходимо конвертировать в формат JSON перед сохранением в БД, так же как и конвертировать обратно при извлечении данных. В данной заметке пример поведения, которое позволит не отвлекаться на такие вещи, достаточно его установить и указать поля которые участвуют в конвертации. После этого поведение будет отслеживать обращения к базе данных и конвертировать данные "на лету".

Проще всего установить в виде расширения: https://github.com/klisl/yii2-json-behavior

Или создать отдельный файл, например в папке common/behaviors:
<?php

namespace common\behaviors;

use yii\base\Behavior;
use yii\base\Event;
use yii\db\ActiveRecord;
use yii\helpers\Json;

/**
 * Поведение для автоматической конвертации свойств объектов ActiveRecord в формат JSON
 * @property string $property Свойство содержащее объект или массив до конвертации в формат JSON
 * @property string $jsonField Поле таблицы для хранения данных в формате JSON
 */
class JsonBehavior extends Behavior
{
    public $property;
    public $jsonField;

    /**
     * Список событий на которые зарегистрировано выполнение указанных методов
     * @return array
     */
    public function events(): array
    {
        return [
            ActiveRecord::EVENT_AFTER_FIND => 'onAfterFind',
            ActiveRecord::EVENT_BEFORE_INSERT => 'onBeforeSave',
            ActiveRecord::EVENT_BEFORE_UPDATE => 'onBeforeSave',
        ];
    }

    public function onAfterFind(Event $event): void
    {
        /** @var ActiveRecord $model */
        $model = $event->sender;
        $jsonField = $this->getJsonField($model);

        $model->{$this->property} = Json::decode($model->getAttribute($jsonField));
    }

    public function onBeforeSave(Event $event): void
    {
        /** @var ActiveRecord $model */
        $model = $event->sender;
        $jsonField = $this->getJsonField($model);

        $model->setAttribute($jsonField, Json::encode($model->{$this->property}));
    }

    protected function getJsonField(ActiveRecord $model): string
    {
        $jsonField = $this->jsonField ?? $this->property;

        if (!$model->hasAttribute($jsonField)){
            throw new \DomainException("Field $jsonField with type JSON does not exist in the table " . $model::tableName());
        }
        return $jsonField;
    }
}

Для подключения данного класса необходимо переопределить метод behaviors в классе нужной модели(сущности):
public function behaviors(): array
{
    return [
        [
            'class' => JsonBehavior::class,
            'property' => 'meta',
            'jsonField' => 'meta_json'
        ]
    ];
}

В свойстве property необходимо указать название свойства в котором содержится массив или объект до конвертации в формат JSON. Для примера используется свойство "meta".
Свойство jsonField используется в случае, когда в таблице базы данных поле для хранения данных в формат JSON имеет другое название. Если названия совпадают, его можно не указывать.
И, конечно нужно указать пространство имен для класса в зависимости от места где вы разместите данное поведение.

Используются события ActiveRecord для отслеживания обращений к базе данных: перед сохранением данные конвертируются в JSON, а сразу после извлечения - обратно.