fin / user-backup-lib
Библиотека PHP для резервного копирования пользовательских данных из нескольких баз данных.
Requires
- php: ^8.0
- illuminate/database: ^8.0
- illuminate/support: ^8.0
Requires (Dev)
- orchestra/testbench: ^6.0
- phpunit/phpunit: ^9.6
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-26 08:49:50 UTC
README
Библиотека для выгрузки, удаления и восстановления данных пользователя по явному плану:
какие строки принадлежат пользователю, задаёт приложение декларацией правил, а не имя колонки
user_id. Выгрузка и удаление отбирают строки одними и теми же селекторами, поэтому бэкап
всегда покрывает то, что будет удалено.
Что в пакете
| Слой | Где | Что делает |
|---|---|---|
| План | src/Plan/* |
Правила таблиц (UserDataRule, TableAction: keep / backupAndDelete / backupOnly / detach), AST селекторов (Equals, InScope, ExistsInParent, AnyOf, MorphReference), компиляция в CompiledUserDataPlan, порядок удаления с проверкой циклов |
| Исполнение | src/Plan/Execution/* |
Обход строк keyset-курсором (в том числе составным), удаление и отвязка порциями, предохранитель по числу строк (RowLimitGuard) |
| Preflight | src/Plan/Preflight/* |
Сверка плана со схемой БД до первого изменения |
| Файлы | src/Services/FileStorageService.php |
Потоковая запись и чтение бэкапа, сжатие и шифрование порциями через Crypt (APP_KEY) |
| Сжатие | src/Services/Compression/* |
gzip встроенным zlib перед шифрованием (BackupStreamCompressor), распаковка с распознаванием по сигнатуре (BackupStreamDecoder) |
Сам план собирает приложение: провайдеры правил по доменам, профили операций, подключения.
Формат файла
- v2 (
saveBackup) — шапка@meta(владелец, версия формата и плана) и секции таблиц с подключением:{"@meta":{...},"tables":[{"connection":"mysql","table":"...","rows":[...]}]}. - v1 (
saveToFile) —{"table":[rows]}без шапки. Пишется только для совместимости и тестов, читается всегда.
Запись атомарная: файл пишется во временный, порция дописывается до конца, закрытие
проверяется, готовый файл публикуется переименованием. Недописанный бэкап не может выглядеть
готовым (BackupWriteIncompleteException, BackupFileCloseException).
Сжатие и шифрование
Зашифрованный файл (*.enc) — это строки, каждая строка — шифротекст Crypt порции
сжатого JSON. Сжатие делается до шифрования: шифротекст уже не сжимается, а base64 в
конверте Crypt раздувает данные ещё в 1,78 раза.
- Формат — gzip,
zlibуровня 6, потоково (deflate_init/inflate_init): файл целиком в память не читается. Замер на реальных бэкапах: 163 МБ JSON → 7 МБ меньше чем за секунду, итоговый файл в 13–30 раз меньше прежнего. - Файлы, записанные до сжатия, читаются без изменений: сжатый поток распознаётся по сигнатуре
gzip
1f 8bпосле расшифровки, а JSON с байта0x1fначинаться не может. - Оборванный или повреждённый сжатый поток не принимается за целый:
BackupDecompressionException(user_backup.decompression_failed, стадия и число прочитанных байт вcontext()). Ошибка сжатия —BackupCompressionException. - Незашифрованный файл (
encrypt: false) пишется простым JSON без сжатия. - Сжатие и распаковка подменяются биндингом контрактов
BackupStreamCompressorиBackupStreamDecoder;FileStorageServiceо формате сжатия не знает.
Чтение
use UserDataBackup\Contracts\FileStorageServiceInterface; $storage = app(FileStorageServiceInterface::class); $header = $storage->readHeader($path); // v1 → BackupHeader::legacy() foreach ($storage->streamBackupData($path) as $entry) { // ['connection' => ..., 'table' => ..., 'row' => [...]] }
Что удалено
Старый движок эвристического удаления и выгрузки по колонке user_id
(UserBackupService, UserBackupServiceFactory, UserDataDeletionService, BackupProcessor,
DatabaseService, UserDataScope, конфиг user-backup.connections) удалён: его заменил план.
Гайд docs/user-backup-guide.md описывает удалённый API и оставлен
как история.
Тесты
vendor/bin/phpunit