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

Сидеры

Внимание

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

  • Содержание
  • Обзор
  • Seeder
    • run()
    • insert()
    • call()
  • DatabaseManager
    • seed()
  • Примеры
    • Простой сидер
    • Сидер с вызовом других сидеров
    • Сидер пользователей
    • Сидер настроек
    • Сидер с фабрикой
    • Идемпотентный сидер
    • Сидер с параметрами
    • Сидер только для dev-окружения
    • Запуск
    • Через PHP
  • Рекомендации
  • FAQ
    • Как сделать сидер идемпотентным?
    • Как передать параметры в сидер?
    • Как выполнить сидер только в dev?
    • Чем сидер отличается от фабрики?
    • Как получить ID последней вставленной записи в сидере?
    • Можно ли использовать сидер без класса?

Полное руководство по созданию и использованию сидеров в IO7 фреймворке.

Содержание

  • Обзор
  • Seeder
    • run()
    • insert()
    • call()
  • DatabaseManager
    • seed()
  • Примеры
  • Рекомендации
  • FAQ

Обзор

Сидеры используются для заполнения базы данных начальными данными:

  • Административные учётные записи
  • Справочники (роли, категории, настройки)
  • Тестовые данные для разработки
  • Данные для staging-окружения

Пространство имён: IO\Database

Файл: src/modules/io7/php/Database/Seeder.php


Seeder

Абстрактный базовый класс сидера. Каждый сидер должен наследоваться от этого класса и реализовывать метод run().


run()

abstract public function run(): void

Основной метод сидера — содержит логику заполнения данных. Вызывается автоматически при выполнении сидера.

public function run(): void
{
    $this->insert('users', [
        'login' => 'admin',
        'name'  => 'Администратор',
        'email' => 'admin@example.com',
    ]);
}

insert()

protected function insert(string $table, array $data): void

Вставить одну запись в таблицу.

ПараметрТипОписаниеЗначение по умолчаниюОбязателен
$tablestringИмя таблицы—Да
$dataarrayАссоциативный массив данных—Да
$this->insert('users', [
    'login'         => 'admin',
    'name'          => 'Администратор',
    'email'         => 'admin@example.com',
    'password_hash' => password_hash('admin123', PASSWORD_DEFAULT),
    'role'          => 'admin',
    'active'        => true,
]);

call()

protected function call(string $seederClass): void

Выполнить другой сидер по имени класса. Позволяет организовать порядок выполнения сидеров.

ПараметрТипОписаниеЗначение по умолчаниюОбязателен
$seederClassstringПолное имя класса сидера—Да
$this->call(RolesSeeder::class);
$this->call(SettingsSeeder::class);
$this->call(UserSeeder::class);

DatabaseManager

seed()

public static function seed(?string $seederClass = null): int

Выполнить сидер(ы). Если класс не указан — выполняются все найденные сидеры из директории seeders.

ПараметрТипОписаниеЗначение по умолчаниюОбязателен
$seederClass?\stringИмя класса сидера. null — выполнить всеnullНет

Возвращает: int — количество выполненных сидеров

use IO\Database\DatabaseManager;

// Один сидер
DatabaseManager::seed(UserSeeder::class);

// Все сидеры
DatabaseManager::seed();

Примеры

Простой сидер

Файл: database/seeders/RoleSeeder.php

<?php
use IO\Database\Seeder;

class RoleSeeder extends Seeder
{
    public function run(): void
    {
        $roles = [
            ['name' => 'admin',   'description' => 'Администратор'],
            ['name' => 'manager', 'description' => 'Менеджер'],
            ['name' => 'user',    'description' => 'Пользователь'],
            ['name' => 'guest',   'description' => 'Гость'],
        ];

        foreach ($roles as $role) {
            $this->insert('roles', $role);
        }
    }
}

Сидер с вызовом других сидеров

Файл: database/seeders/DatabaseSeeder.php

<?php
use IO\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this->call(RolesSeeder::class);
        $this->call(SettingsSeeder::class);
        $this->call(UserSeeder::class);
    }
}

Сидер пользователей

Файл: database/seeders/UserSeeder.php

<?php
use IO\Database\Seeder;

class UserSeeder extends Seeder
{
    public function run(): void
    {
        $this->insert('users', [
            'login'         => 'admin',
            'name'          => 'Администратор',
            'email'         => 'admin@example.com',
            'password_hash' => password_hash('admin123', PASSWORD_DEFAULT),
            'role'          => 'admin',
            'active'        => true,
        ]);

        $this->insert('users', [
            'login'         => 'manager',
            'name'          => 'Менеджер',
            'email'         => 'manager@example.com',
            'password_hash' => password_hash('manager123', PASSWORD_DEFAULT),
            'role'          => 'manager',
            'active'        => true,
        ]);

        // Тестовые пользователи
        for ($i = 1; $i <= 10; $i++) {
            $this->insert('users', [
                'login'         => "user_{$i}",
                'name'          => "Пользователь {$i}",
                'email'         => "user{$i}@example.com",
                'password_hash' => password_hash('password', PASSWORD_DEFAULT),
                'role'          => 'user',
                'active'        => true,
            ]);
        }
    }
}

Сидер настроек

Файл: database/seeders/SettingsSeeder.php

<?php
use IO\Database\Seeder;

class SettingsSeeder extends Seeder
{
    public function run(): void
    {
        $settings = [
            ['key' => 'site_name',     'value' => 'Мой сайт'],
            ['key' => 'site_email',    'value' => 'info@example.com'],
            ['key' => 'timezone',      'value' => 'Europe/Moscow'],
            ['key' => 'items_per_page', 'value' => '25'],
            ['key' => 'allow_registration', 'value' => 'true'],
        ];

        foreach ($settings as $setting) {
            $this->insert('settings', $setting);
        }
    }
}

Сидер с фабрикой

Файл: database/seeders/ProductSeeder.php

<?php
use IO\Database\Seeder;

class ProductSeeder extends Seeder
{
    public function run(): void
    {
        $faker = \Faker\Factory::create('ru_RU');

        $categories = ['Электроника', 'Одежда', 'Книги', 'Продукты'];

        foreach ($categories as $category) {
            $this->insert('categories', ['name' => $category]);
            $categoryId = \IO\Database\SqlConnection::connection()
                ->getPdo()->lastInsertId();

            for ($i = 0; $i < 20; $i++) {
                $this->insert('products', [
                    'category_id' => $categoryId,
                    'name'        => $faker->words(3, true),
                    'description' => $faker->paragraph,
                    'price'       => $faker->randomFloat(2, 10, 10000),
                    'in_stock'    => $faker->boolean(80),
                ]);
            }
        }
    }
}

Идемпотентный сидер

<?php
use IO\Database\Seeder;
use IO\Database\SqlConnection;

class RoleSeeder extends Seeder
{
    public function run(): void
    {
        $roles = [
            ['name' => 'admin',   'description' => 'Администратор'],
            ['name' => 'manager', 'description' => 'Менеджер'],
            ['name' => 'user',    'description' => 'Пользователь'],
        ];

        foreach ($roles as $role) {
            $exists = SqlConnection::table('roles')
                ->where('name', $role['name'])
                ->exists();

            if (!$exists) {
                $this->insert('roles', $role);
            }
        }
    }
}

Сидер с параметрами

<?php
use IO\Database\Seeder;

class UserSeeder extends Seeder
{
    private int $count;

    public function __construct(int $count = 10)
    {
        $this->count = $count;
    }

    public function run(): void
    {
        for ($i = 1; $i <= $this->count; $i++) {
            $this->insert('users', [
                'login'         => "user_{$i}",
                'name'          => "Пользователь {$i}",
                'email'         => "user{$i}@example.com",
                'password_hash' => password_hash('password', PASSWORD_DEFAULT),
                'role'          => 'user',
                'active'        => true,
            ]);
        }
    }
}

// Использование
$seeder = new UserSeeder(50);
$seeder->run();

Сидер только для dev-окружения

<?php
use IO\Database\Seeder;

class TestDataSeeder extends Seeder
{
    public function run(): void
    {
        if (getenv('CLOUD_ENV') !== 'dev') {
            return;
        }

        $faker = \Faker\Factory::create('ru_RU');

        for ($i = 0; $i < 100; $i++) {
            $this->insert('users', [
                'login'         => $faker->unique()->userName,
                'name'          => $faker->name,
                'email'         => $faker->unique()->safeEmail,
                'password_hash' => password_hash('password', PASSWORD_DEFAULT),
                'role'          => 'user',
                'active'        => true,
            ]);
        }
    }
}

Запуск

# Все сидеры
php iocli db:seed

# Один сидер
php iocli db:seed --class=UserSeeder

Через PHP

use IO\Database\DatabaseManager;

DatabaseManager::init('/path/to/project');

// Все сидеры
DatabaseManager::seed();

// Один сидер
DatabaseManager::seed(UserSeeder::class);

// Цепочка
DatabaseManager::seed(RolesSeeder::class);
DatabaseManager::seed(SettingsSeeder::class);
DatabaseManager::seed(UserSeeder::class);

Рекомендации

  1. Создайте DatabaseSeeder как точку входа для всех сидеров
  2. Используйте call() для организации порядка выполнения
  3. Проверяйте существование записей перед вставкой (идемпотентность)
  4. Не используйте сидеры для продакшен-данных (кроме начальных)
  5. Используйте фабрики для генерации тестовых данных
  6. Храните сидеры в database/seeders/
  7. Именование: ModelNameSeeder.php или DescriptiveNameSeeder.php
  8. Передавайте параметры через конструктор для гибкости

FAQ

Как сделать сидер идемпотентным?

public function run(): void
{
    $exists = \IO\Database\SqlConnection::table('roles')
        ->where('name', 'admin')
        ->exists();

    if (!$exists) {
        $this->insert('roles', ['name' => 'admin', 'description' => 'Администратор']);
    }
}

Как передать параметры в сидер?

class UserSeeder extends Seeder
{
    private int $count;

    public function __construct(int $count = 10)
    {
        $this->count = $count;
    }

    public function run(): void
    {
        for ($i = 0; $i < $this->count; $i++) {
            $this->insert('users', [...]);
        }
    }
}

// Использование
$seeder = new UserSeeder(50);
$seeder->run();

Как выполнить сидер только в dev?

public function run(): void
{
    if (getenv('CLOUD_ENV') !== 'dev') {
        return;
    }

    // Тестовые данные только для dev
    ...
}

Чем сидер отличается от фабрики?

  • Сидер — заполняет БД реальными/тестовыми данными (выполняет insert() в БД)
  • Фабрика — генерирует структурированные данные программно (может не сохранять в БД)

Как получить ID последней вставленной записи в сидере?

$this->insert('categories', ['name' => 'Electronics']);
$categoryId = \IO\Database\SqlConnection::connection()
    ->getPdo()->lastInsertId();

Можно ли использовать сидер без класса?

Да, через DatabaseManager::seed() без параметров выполняются все сидеры из директории database/seeders/.

Prev
Миграции
Next
Query Builder