BMC IO DocsBMC IO Docs
IO v6
IO v7
Notes
Docs
IO v6
IO v7
Notes
Docs
  • IO Framework v7

    • О фреймворке
    • Что изменилось в 7 версии
    • IO7 Framework vs Laravel 13 — Сравнение
    • Структура
    • Варианты проектов
    • Доступ к участкам проекта
    • Разворачивание нового проекта
    • Установка проекта
    • Запуск локальной разработки
  • API

    • Обзор API
    • IOCore::call() и IOCore::callAction()
    • Создание API
  • CLI

    • Обзор CLI
    • iocli
    • Кастомные CLI команды
  • Работа с базами данных

    • Обзор работы с базами данных
    • Cron / Планировщик задач (Schedule)
    • Фабрики
    • Миграции
    • Сидеры
    • Query Builder
    • Подключение MinIO
    • Подключение MongoDB
    • Подключение MySQL
    • Подключение PostgreSQL
    • Подключение ProxySQL
    • Подключение RabbitMQ
    • Подключение Redis
  • Логирование

    • Обзор логирования
    • IOEvent - Логирование событий
    • Pinba (PinbaManager) - Профилировщик
  • Модели

    • Обзор моделей
    • CRUD операции
    • Связи моделей
  • Очереди

    • Обзор очередей
    • RabbitMQ
  • Маршруты

    • Обзор маршрутов
    • Определение маршрутов
    • Middleware
  • Сессии

    • Обзор сессий
    • Кроссдоменная SSO
    • JWT авторизация
    • Социальная авторизация
    • OAuth2
    • Keycloak
  • Twig

    • Обзор Twig
    • Формы (FormBuilder)
    • Twig функции
  • Тестирование

    • Обзор тестирования
    • Unit тесты
  • Backend

    • Настройки проекта Conf.php
    • Настройки модуля Module.php
    • Настройки composer
    • Функции фреймворка
    • Вспомогательные функции (Helpers)
    • Глобальные переменные
    • Константы фреймворка
    • Event класс
    • Core класс
    • Route и работа с ними
    • Request и работа с ними
    • Middleware и работа с ними
    • Class и работа с ними
    • Api model и работа с ними
    • Template и работа с ними
    • Мультиязычность и словарь фраз
    • Bin скрипты и работа с ними
    • Cron скрипты и работа с ними
    • $ioSession и работа с сессией
    • $ioHash и работа с кешем
    • $ioXCache и работа с кешем
    • $iodb и работа с базой данных
    • Миграции
  • Frontend

    • Twig шаблонизатор и работа с ним
    • Twig функции
    • Twig фильтры
    • Twig контекст
    • Настройка NPM
    • Сборка Frontend составляющей
    • Обращение к Api через JS
    • Хранилище (store)
    • Навигация в хосте
    • Навигация в микрофронтенде
    • Параметры микрофронтенда
    • Проверка полномочий
  • Tailux UI Компоненты

    • Базовый UI

      • AvatarDot
      • Avatar
      • Badge
      • Button
      • Card
      • ConfirmModal
      • Divider
      • Highlight
      • Tag
    • Загрузка

      • Circlebar
      • Progress
      • Skeleton
      • Spinner
    • Навигация

      • Accordion
      • AccordionButton
      • AccordionHeader
      • AccordionItem
      • AccordionPanel
      • AccordionProvider
      • Pagination
      • PaginationControl
      • PaginationItems
      • PaginationDots
      • PaginationFirst
      • PaginationLast
      • PaginationNext
      • PaginationPrevious
    • Отображение данных

      • Box
      • Collapse
      • ContextualHelp
      • ScrollShadow
      • Timeline
      • TimelineItem
    • Элементы таблиц

      • Table
      • CollapsibleSearch
      • ColumnFilter
      • CopyableCell
      • DateFilter
      • FacetedFilter
      • FilterSelector
      • PaginationSection
      • RadioFilter
      • RangeFilter
      • ResponsiveFilter
      • RoleFilter
      • SelectedRowsActions
      • TableColumnVisibility
      • TableSettings
      • TableSortIcon
    • Элементы форм

      • Checkbox
      • Combobox
      • DatePicker
      • Filepond
      • Input
      • Listbox
      • Radio
      • Range
      • Select
      • StyledSwitch
      • Swap
      • SwapOn
      • SwapOff
      • Switch
      • Textarea
      • TextEditor
      • Upload

CRUD операции IO7

Внимание

Данная статья документации написана нейросетью. Возможны некоторые расхождения и неточность информации!

  • IO\SqlClass — статические методы
    • search()
    • findItem()
    • getByPkid()
    • updateByFilter()
    • tablename()
    • rules()
  • IO\Api\CrudApi — CRUD через API
    • struct()
    • doSearch()
    • doGetByID()
    • doCreate()
    • doSave()
    • doDelete()
    • Хуки CrudApi
    • Получение текущего элемента
    • saveItem()
  • Фильтры API
  • См. также
  • soft_delete и doRestore
    • soft_delete флаг
    • doRestore()
  • struct() — class обязателен
    • getSqlClass()

IO7 предоставляет два уровня CRUD: статические методы SqlClass для прямого доступа к БД и ** CrudApi** для построения REST-like API.


IO\SqlClass — статические методы

search()

Поиск записей с фильтрами, сортировкой, пагинацией.

public static function search(array $params): array

Параметры ($params):

КлючТипЗначение по умолчаниюОбязателенОписание
filterarray<string, mixed>[]НетФильтры WHERE
outstring'object'НетФормат вывода: 'object' или 'array'
limitint1000НетМаксимум записей
startint0НетСмещение (OFFSET)
orderarray<string, string>[]НетСортировка ['field' => 'asc'|'desc']
fieldsstring[][]НетСписок полей для SELECT
joinstring|string[][]НетJOIN выражения
groupbystring[][]НетGROUP BY поля
distinctint0НетDISTINCT (1 или 0)

Возвращает: array{error_str: string, error_code: int, res: array, count: int, time: int}

$result = \IO\Unit::search([
    'filter' => ['is_active' => 1],
    'out'    => 'array',
    'limit'  => 50,
    'order'  => ['pkid' => 'asc'],
]);

// $result['res']     — массив записей
// $result['count']   — общее количество
// $result['error_code'] — EIO_OK при успехе

findItem()

Поиск одной записи.

public static function findItem(array $params): ?array
$item = \IO\Unit::findItem([
    'filter' => ['pkid' => 42],
]);
// ['pkid' => 42, 'name' => '...', ...] или null

getByPkid()

Поиск по первичному ключу.

public static function getByPkid($pkids, string $out = 'object'): array

Параметры:

ПараметрТипЗначение по умолчаниюОбязателенОписание
$pkidsint|int[]—ДаID или массив ID
$outstring'object'Нет'object' или 'array'
$result = \IO\Unit::getByPkid(42);
$result = \IO\Unit::getByPkid([1, 2, 3], 'array');

updateByFilter()

Массовое обновление по фильтру.

public static function updateByFilter(array $filter, array $data): int

Возвращает: 1 при успехе, -1 при ошибке.

$ok = \IO\Unit::updateByFilter(
    ['pkid' => 5],
    ['is_deleted' => 1, 'gmtimeChange' => iogetdbtimeutc(time())]
);

tablename()

Возвращает имя таблицы.

public static function tablename(): string
$name = \IO\Unit::tablename(); // 'lib_units'

rules()

Разрешения для IO\Core::call().

public static function rules(): array
$perms = \IO\Unit::rules();
// ['static' => [], 'object' => []]

IO\Api\CrudApi — CRUD через API

CrudApi расширяет CoreApi и предоставляет готовые CRUD-действия.

struct()

Определение структуры API. Обязательно для переопределения.

public static function struct(): array
class UserApi extends \IO\Api\CrudApi
{
    public static function struct(): array
    {
        return [
            'class' => \IO\Classes\User::class,
            'fields' => [
                'pkid'    => ['type' => 'int'],
                'name'    => ['type' => 'string', 'label' => 'Имя'],
                'email'   => ['type' => 'string', 'label' => 'Email'],
                'is_deleted' => ['type' => 'int', 'virtual' => true],
            ],
            'primary' => ['pkid'],
        ];
    }
}

doSearch()

Поиск записей. Вызывается через IO\Core::callAction().

public function doSearch(ApiResult $result, array $params): ApiResult
$response = \IO\Core::callAction('app.model.user.search', [
    'filter' => ['status' => 'active'],
    'start'  => 0,
    'limit'  => 20,
]);
// $response['items']  — записи
// $response['total']  — общее количество

doGetByID()

Получение записи по ID.

public function doGetByID(ApiResult $result, array $params): ApiResult
$response = \IO\Core::callAction('app.model.user.getByID', ['pkid' => 42]);
// $response['item'] — найденная запись или null

doCreate()

Создание новой записи.

public function doCreate(ApiResult $result, array $params): ApiResult
$response = \IO\Core::callAction('app.model.user.create', [
    'item' => [
        'name'  => 'Иван',
        'email' => 'ivan@example.com',
    ],
]);
// $response['pkid'] — ID новой записи

doSave()

Обновление существующей записи.

public function doSave(ApiResult $result, array $params): ApiResult
$response = \IO\Core::callAction('app.model.user.save', [
    'pkid' => 42,
    'item' => [
        'name' => 'Иван Петров',
    ],
]);

doDelete()

Мягкое удаление (установка is_deleted = 1).

public function doDelete(ApiResult $result, array $params): ApiResult
$response = \IO\Core::callAction('app.model.user.delete', ['pkid' => 42]);

Хуки CrudApi

МетодОписание
onSearchFilter(array $filter): arrayМодификация фильтра перед запросом
onSearchParams(array $params): arrayМодификация параметров поиска
onUpdateData(array $save, array $update): arrayМодификация данных перед сохранением
onUpdateItem(array $save, array $update): voidПобочные эффекты после обновления
class UserApi extends \IO\Api\CrudApi
{
    public function onSearchFilter(array $filter): array
    {
        $filter['is_deleted'] = 0;
        return $filter;
    }

    public function onUpdateData(array $save_data, array $update_data): array
    {
        $update_data['modified_by'] = $this->user->id;
        return $update_data;
    }
}

Получение текущего элемента

Внутри методов doSave() и doCreate() доступны:

$this->item       // текущий объект модели (Eloquent)
$this->item_pkid  // ID текущего элемента

saveItem()

Сохранение данных в БД с учётом структуры полей.

public function saveItem(array $save_data): void

Метод автоматически:

  • Исключает виртуальные и readonly поля
  • Вызывает onUpdateData() для трансформации
  • Вызывает onUpdateItem() для побочных эффектов
  • Вызывает $item->save()

Фильтры API

CrudApi поддерживает операторы в ключах фильтра:

ОператорПримерОписание
(нет)statusРавно (=)
==statusРавно (явно)
!=!=statusНе равно
>age>25Больше
<age<50Меньше
>=age>=25Больше или равно
<=age<=50Меньше или равно
%%nameСодержит (LIKE)
$or$orЛогическое ИЛИ
$and$andЛогическое И
$response = \IO\Core::callAction('app.model.user.search', [
    'filter' => [
        '!=status' => 'deleted',
        'age>25'   => null,
        '%name'    => 'Иван',
    ],
]);

См. также

  • Обзор моделей
  • Связи
  • Создание API

soft_delete и doRestore

soft_delete флаг

В struct() можно указать soft_delete => true для мягкого удаления:

public static function struct(): array
{
    return [
        'class' => Role::class,
        'fields' => [...],
        'soft_delete' => true,   // is_deleted = 1 (мягкое удаление)
    ];
}
ЗначениеdoDelete() поведение
trueУстанавливает is_deleted = 1, gmtimeChange = now()
false (по умолчанию)DELETE FROM table WHERE pkid = ?

doRestore()

Восстановление мягко удалённой записи (только при soft_delete = true).

public function doRestore(ApiResult $result, array $params): ApiResult
$response = \IO\Core::callAction('app.model.user.restore', ['pkid' => 42]);
УсловиеРезультат
soft_delete = trueUPDATE table SET is_deleted = 0 WHERE pkid = ?
soft_delete = falseВозвращает ошибку "Restore not supported"

struct() — class обязателен

Поле class в struct() обязательно. Если не указано — выбрасывается RuntimeException.

// ✅ Правильно
public static function struct(): array
{
    return [
        'class' => Role::class,     // обязательно
        'fields' => [...],
        'primary' => ['pkid'],
        'soft_delete' => true,
    ];
}

// ❌ Ошибка — RuntimeException
public static function struct(): array
{
    return [
        'fields' => [...],
    ];
}

Ошибка:

RuntimeException: CrudApi: 'class' is required in struct().
Define it in your API class: struct()['class'] = YourModel::class

getSqlClass()

Внутренний метод, вызывается автоматически. Возвращает имя класса модели или выбрасывает RuntimeException.

protected static function getSqlClass(): string

Используется во всех CRUD-методах: doSearch, doGetByID, doCreate, doSave, doDelete, doRestore.

Prev
Обзор моделей
Next
Связи моделей