mb4it / bitrix-migration
Laravel-style versioned migrations for 1C-Bitrix (MB\Bitrix\Database\Migrations). Ships its console commands on top of mb4it/bitrix-console.
Requires
- php: ^8.2
- mb4it/bitrix-console: ^0.1
This package is auto-updated.
Last update: 2026-07-26 15:13:11 UTC
README
Версионируемые миграции для 1С-Битрикс в стиле Laravel: класс миграции с
up()/down(), таблица-леджер применённых версий, батчи, откат, статус. Плюс
fluent-билдеры и экспортёры сущностей Битрикса (инфоблоки, HL-блоки, агенты,
почта, опции, пользователи/группы, sitemap) для генерации миграций из живой БД.
Namespace — MB\Bitrix\Database\Migrations\.
Самодостаточный пакет: зависит от ядра 1С-Битрикс и от mb4it/bitrix-console
(движок + свои console-команды), но НЕ от mb4it/bitrix-support. Леджер
MigrationVersionTable extends \Bitrix\Main\ORM\Data\DataManager; DI-обвязка
(биндинги Migrator и пр.) и CLI-команды регистрируются через провайдер пакета,
который консоль подхватывает автоматически (discovery по extra.mb-console.providers).
Требования
- PHP
^8.2 - 1С-Битрикс (модуль
main; отдельные экспортёры грузятiblock/highloadblock/seo) - Для запуска из консоли —
mb4it/bitrix-console(командыmigrate*,make:migration*)
Установка
Пакет — path-репозиторий в composer.json потребителя (модуля/проекта):
{
"require": {
"mb4it/bitrix-migration": "@dev"
}
}
composer update mb4it/bitrix-migration
Подключение — автоматическое: пакет объявляет свой console-провайдер в
composer.json → extra.mb-console.providers, а mb4it/bitrix-console подхватывает
его через Console\PackageManifest (читает vendor/composer/installed.json).
Никакой ручной регистрации не нужно. mb4it/bitrix-support не требуется.
Быстрый старт
Сам движок — библиотека; CLI-команды даёт mb4it/bitrix-console. Обычно ставят
консоль (миграции придут транзитивно) — и всё работает сразу, без настройки:
composer require mb4it/bitrix-console
Появится самодостаточный бинарь vendor/bin/bx (далее — просто bx):
bx make:migration create_orders_table # создать файл в local/migrations # отредактируйте up()/down() в созданном файле, затем: bx migrate # применить (создаст леджер при первом запуске) bx migrate:status # ran / pending / batch bx migrate:rollback --force # откатить последний батч
Нужно только программное использование, без CLI? Ставьте один движок:
composer require mb4it/bitrix-migration
и вызывайте app(\MB\Bitrix\Database\Migrations\Migrator::class) (см.
«Программное использование»).
Что внутри
| Класс | Назначение |
|---|---|
Migration |
Базовый абстрактный класс миграции: up() / down(), connection(), statement(). |
Migrator |
Движок: применение pending, откат батчей, fresh, статус. Поддерживает scope; ставит контекст миграции (имя + каталог) вокруг up()/down(). |
MigrationCreator |
Генератор timestamped-файла миграции из стаба (make:migration). |
PathRegistry |
Реестр каталогов с миграциями (по умолчанию local/migrations). |
Repository\{MigrationRepository, DatabaseMigrationRepository} |
Интерфейс + реализация леджера поверх ORM. |
Entity\MigrationVersionTable |
DataManager, таблица mb_migration_version (леджер версий). |
Entity\MigrationCreatedTable |
mb_migration_created — что миграция СОЗДАЛА (для не-разрушающего отката). |
Entity\MigrationSnapshotTable |
mb_migration_snapshot — прежнее состояние обновлённых сущностей (для восстановления полей). PAYLOAD расширяется до LONGTEXT. |
Support\CreationTracker |
Трекинг созданного + снимков; контекст текущей миграции/каталога. |
Support\PortableFile |
Переносимые файлы: дескриптор {NAME,TYPE,DESCRIPTION} + байты (base64 CONTENT или sidecar PATH). |
Support\{Blueprint, MigrationWriter, PhpPrinter, Resolver} |
Генерация файла миграции из экспортёра, печать PHP, переносимый резолв сущности. |
Builders\*, Export\* |
Fluent-билдеры (apply/remove) и экспортёры живых сущностей → Blueprint. |
Console\* |
console-команды пакета (migrate*, make:migration*) + провайдер. |
Три таблицы (создаёт migrate:install, а также ленивое авто-создание):
mb_migration_version— леджер:ID,MIGRATION(для модуля<id>:<файл>),BATCH,APPLIED_AT.mb_migration_created— сущности, созданные миграцией (чтобы откат удалял только их).mb_migration_snapshot— снимок прежних значений обновлённых сущностей (чтобы откат восстанавливал поля, а не удалял сущность).
Как написать миграцию
Файл миграции — обычный PHP-файл, который возвращает анонимный экземпляр
Migration. Имя файла timestamped: 2026_07_07_120000_create_orders_table.php.
<?php declare(strict_types=1); use MB\Bitrix\Database\Migrations\Migration; return new class extends Migration { private const TABLE = 'my_orders'; public function up(): void { $this->statement( 'CREATE TABLE IF NOT EXISTS ' . self::TABLE . ' (' . 'ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, ' . 'TITLE VARCHAR(255) NOT NULL' . ')' ); } public function down(): void { $this->statement('DROP TABLE IF EXISTS ' . self::TABLE); } };
Внутри up()/down() доступны:
$this->connection()→Bitrix\Main\DB\Connection;$this->statement(string $sql)→ выполнить SQL;- весь D7 ORM; а при установленном
mb4it/bitrix-support— глобальные хелперыapp(),config(),module().
down() можно оставить пустым — тогда миграция необратима (rollback просто удалит
запись из леджера).
Схему таблиц ORM-сущностей (
Storage\Base) удобно накатывать прямо из миграции:MyEntityTable::migrate(\Bitrix\Main\Application::getConnection()).
Где лежат файлы
- Проектные —
local/migrations/(путь по умолчанию изPathRegistry). - Модульные —
<module>/migrations/(напр.local/modules/my.module/migrations/).
Модульные миграции изолированы в леджере через scope: имя хранится как
<moduleId>:<файл>, поэтому проектные и модульные миграции не смешиваются и
откатываются независимо. Пустой scope — проект.
Запуск (через mb4it/bitrix-console)
bx make:migration create_orders_table # создать файл в local/migrations bx migrate # применить pending (новый батч) bx migrate:status # статус (ran / pending / batch) bx migrate:rollback --force # откатить последний батч bx migrate:fresh --force # откатить всё и накатить заново # то же для миграций модуля (scope = id модуля): bx make:migration create_x --module my.module bx migrate --module my.module bx migrate:status --module my.module bx migrate:rollback --module my.module --force
Любая команда принимает --format=json для машиночитаемого вывода (ИИ-агент).
migrate:install создаёт все три служебные таблицы (mb_migration_version,
mb_migration_created, mb_migration_snapshot) — идемпотентно; они также
создаются лениво при первом обращении.
Генерация миграций из живых сущностей
Экспортёры читают существующую сущность Битрикса и пишут файл миграции (up()
воссоздаёт, down() откатывает). Команды и их опции — в README пакета
mb4it/bitrix-console: make:migration:options,
:iblock, :iblock-elements, :hlblock, :hlblock-elements, :agents,
:mail, :user-groups, :users, :sitemap.
Выборочный экспорт инфоблока: --properties=CODE,… / --no-properties,
--sections=ID|CODE|XML_ID,… / --no-sections, --with-elements.
Те же билдеры доступны и для ручного написания:
\MB\Bitrix\Database\Migrations\Builders\OptionBuilder::make('main','x')->value('1')->apply();.
Переносимость между сайтами
Билдеры резолвят сущность по символьному ключу (CODE / XML_ID); записанный первичный ID используется лишь как фолбэк для сущностей без ключа. Поэтому миграция, перенесённая на другой сайт (где тот же ID занят несвязанной сущностью), не перезапишет чужую запись: она найдёт цель по ключу либо создаст новую.
Не-разрушающий откат и восстановление полей
down() не удаляет вслепую. Для каждой затронутой сущности:
- создана этой миграцией → удалить;
- существовала и лишь обновлена → восстановить прежние значения полей из
снимка (
mb_migration_snapshot), не удаляя сущность; - иначе → не трогать.
Покрыты: инфоблоки (поля + привязка к сайтам), свойства (поля + список значений
enum + LINK_IBLOCK), разделы, элементы (поля + значения свойств). Вне
контекста миграции (ручной вызов билдера) remove() работает как раньше —
удаляет.
Перенос файлов
Картинки элементов (PREVIEW_PICTURE / DETAIL_PICTURE) и файловые свойства
(тип F, одиночные и множественные) переносятся как самодостаточные файлы:
MigrationWriter выносит их в sidecar-папку files/<миграция>/, а в .php
остаётся ссылка PATH. При apply() файл заливается заново (новый b_file),
при откате — восстанавливается из снимка. Списочные значения переносятся по
enum-id; пустые — очищают свойство.
Важно: миграция теперь — это
.phpплюс папкаfiles/<миграция>/. Переносите и коммитьте их вместе. Экспорт файла возможен только там, где физический файл существует; иначе файл просто пропускается.
Программное использование
Migrator разрешается из контейнера. При наличии mb4it/bitrix-support
доступен глобальный хелпер app(); в standalone-режиме резолвьте через контейнер
консоли или соберите объект напрямую.
use Bitrix\Main\Application as Bitrix; use MB\Bitrix\Database\Migrations\Migrator; use MB\Bitrix\Database\Migrations\PathRegistry; use MB\Bitrix\Database\Migrations\Repository\DatabaseMigrationRepository; // с mb4it/bitrix-support: $migrator = app(Migrator::class); // или app('migrator') // standalone (без support) — прямая сборка: $docRoot = rtrim(Bitrix::getDocumentRoot(), '/\\'); $migrator = new Migrator( new DatabaseMigrationRepository(), new PathRegistry($docRoot . '/local/migrations'), ); $applied = $migrator->run(); // применить pending (проект) $reverted = $migrator->rollback(steps: 1); // откатить последний батч $status = $migrator->status(); // [{migration, ran, batch}, ...] // для модуля — передать путь и scope: $applied = $migrator->run(['/abs/path/my.module/migrations'], 'my.module');
API Migrator
| Метод | Описание |
|---|---|
run(?array $paths = null, string $scope = ''): array |
Применить все pending в scope одним батчем. Возвращает имена. |
rollback(int $steps = 1, ?array $paths = null, string $scope = ''): array |
Откатить N последних батчей scope. |
reset(?array $paths = null, string $scope = ''): array |
Откатить всё в scope. |
status(?array $paths = null, string $scope = ''): array |
[{migration, ran, batch}]. |
getMigrationFiles(array $paths): array |
basename => путь, отсортировано. |
Биндинги контейнера
| Ключ | Класс |
|---|---|
migrator / Migrator::class |
Migrator (singleton) |
migration.repository / MigrationRepository::class |
DatabaseMigrationRepository |
migration.creator / MigrationCreator::class |
MigrationCreator (singleton) |
PathRegistry::class |
PathRegistry (singleton, seed = local/migrations) |
Кастомный путь по умолчанию
PathRegistry по умолчанию засеян local/migrations. Чтобы добавить свои
каталоги (например, для авто-подхвата), переопределите singleton в своём
ServiceProvider:
$this->app->singleton(PathRegistry::class, fn () => new PathRegistry( $docRoot . '/local/migrations', $docRoot . '/local/modules/my.module/migrations', ));