Часто возникает задача сохранить в одном поле базы данных сложную структуру: массив настроек, JSON-объект или список ID.
D7 ORM позволяет автоматизировать процесс «упаковки» данных при записи и «распаковки» при чтении.
Вариант 1: Встроенная сериализация (для serialize)
Если вам подходит стандартная PHP-сериализация, у полей TextField и StringField есть готовая опция serialized.
// В методе getMap() вашей сущности
new Entity\TextField('SETTINGS', [
'serialized' => true
])Теперь вы можете передавать массив в add/update, и он вернется массивом в getList.
Минус: Данные в БД будут лежать в формате PHP serialize, который трудно читать и нельзя использовать в SQL-запросах (JSON удобнее).
Вариант 2: Кастомная модификация (для JSON)
Если мы хотим хранить данные в формате JSON (что является современным стандартом), нам помогут колбэки save_data_modification и fetch_data_modification.
Пример описания поля в getMap():
new Entity\TextField('PARAMS', [
// Преобразование перед записью в БД
'save_data_modification' => function () {
return [
function ($value) {
// Если передали массив, кодируем в JSON
if (is_array($value) || is_object($value)) {
return json_encode($value, JSON_UNESCAPED_UNICODE);
}
return $value;
}
];
},
// Преобразование после чтения из БД
'fetch_data_modification' => function () {
return [
function ($value) {
// Декодируем JSON обратно в массив
if (is_string($value) && !empty($value)) {
return json_decode($value, true);
}
return [];
}
];
}
])Как с этим работать
Теперь ORM делает всю грязную работу за вас.
// Сохраняем массив
MyTable::add([
'NAME' => 'Item 1',
'PARAMS' => ['color' => 'red', 'size' => 'XL'] // Передаем массив!
]);
// Читаем
$item = MyTable::getByPrimary(1)->fetch();
echo $item['PARAMS']['color']; // red (Это уже массив!)В базе данных при этом будет лежать строка: {«color»:»red»,»size»:»XL»}.
Важно: Этот механизм работает на уровне PHP. Вы не сможете сделать эффективную выборку средствами SQL по содержимому этого JSON (например, «найти все, у кого color=red»), если ваша СУБД не поддерживает JSON-индексы. Но для хранения настроек или логов это идеальное решение.
Вывод:
Используйте save_data_modification, чтобы превратить простые текстовые поля вашей БД в хранилища сложных структур данных.
Это избавляет от ручного вызова json_encode/decode по всему коду проекта.
save_data_modification, fetch_data_modification, D7 ORM, serialized, хранение массива в БД, JSON в базе данных, ORM callback.