tobento/service-migration
Composer 安装命令:
composer require tobento/service-migration
包简介
A mirgation manager for any PHP application.
README 文档
README
The Migration Service provides a flexible way for handling migrations for PHP applications.
Table of Contents
Getting started
Add the latest version of the Migration service project running this command.
composer require tobento/service-migration
Requirements
- PHP 8.4 or greater
Highlights
- Framework-agnostic, will work with any project
- Decoupled design
Simple Example
Create a migration
namespace App\Blog; use Tobento\Service\Migration\MigrationInterface; use Tobento\Service\Migration\ActionsInterface; use Tobento\Service\Migration\Actions; use Tobento\Service\Migration\Action\FilesCopy; use Tobento\Service\Migration\Action\FilesDelete; use Tobento\Service\Migration\Action\DirCopy; use Tobento\Service\Migration\Action\DirDelete; /** * BlogMigration */ class BlogMigration implements MigrationInterface { /** * Return a description of the migration. * * @return string */ public function description(): string { return 'Blog migration.'; } /** * Return the actions to be processed on install. * * @return ActionsInterface */ public function install(): ActionsInterface { return new Actions( new FilesCopy( files: [ 'dir/to/store/config/' => [ 'dir/blog/config/blog.php', ], ], description: 'Blog configuration files installed.', ), new DirCopy( dir: 'dir/blog/views/', destDir: 'dir/to/store/views/blog/', description: 'Blog view files installed.', ), ); } /** * Return the actions to be processed on uninstall. * * @return ActionsInterface */ public function uninstall(): ActionsInterface { return new Actions( new FilesDelete( files: [ 'dir/to/store/config/' => [ 'blog.php', ], ], description: 'Blog configuration files uninstalled.', ), new DirDelete( dir: 'dir/to/store/views/blog/', description: 'Blog view files uninstalled.', ), ); } }
Install / Uninstall migration
use Tobento\Service\Migration\Migrator; use Tobento\Service\Migration\AutowiringMigrationFactory; use Tobento\Service\Migration\MigrationJsonFileRepository; use Tobento\Service\Migration\MigrationInstallException; use Tobento\Service\Migration\MigrationUninstallException; use Tobento\Service\Container\Container; // Any PSR-11 container $container = new Container(); // Create migrator. $migrator = new Migrator( new AutowiringMigrationFactory($container), new MigrationJsonFileRepository(__DIR__.'/migrations/'), ); // Install a migration. try { $result = $migrator->install(\App\Blog\BlogMigration::class); } catch (MigrationInstallException $e) { // Handle exception. } // Uninstall a migration. if ($migrator->isInstalled(\App\Blog\BlogMigration::class)) { try { $result = $migrator->uninstall(\App\Blog\BlogMigration::class); } catch (MigrationUninstallException $e) { // Handle exception. } }
Documentation
Migration
Create Migration
Your migration class must implement the MigrationInterface:
use Tobento\Service\Migration\MigrationInterface; use Tobento\Service\Migration\ActionsInterface; use Tobento\Service\Migration\Actions; use Tobento\Service\Migration\Action\FilesCopy; use Tobento\Service\Migration\Action\FilesDelete; use Tobento\Service\Migration\Action\DirCopy; use Tobento\Service\Migration\Action\DirDelete; /** * BlogMigration */ class BlogMigration implements MigrationInterface { /** * Return a description of the migration. * * @return string */ public function description(): string { return 'Blog migration.'; } /** * Return the actions to be processed on install. * * @return ActionsInterface */ public function install(): ActionsInterface { return new Actions( new FilesCopy( files: [ 'dir/to/store/config/' => [ 'dir/blog/config/blog.php', ], ], description: 'Blog configuration files installed.', ), new DirCopy( dir: 'dir/blog/views/', destDir: 'dir/to/store/views/blog/', description: 'Blog view files installed.', ), ); } /** * Return the actions to be processed on uninstall. * * @return ActionsInterface */ public function uninstall(): ActionsInterface { return new Actions( new FilesDelete( files: [ 'dir/to/store/config/' => [ 'blog.php', ], ], description: 'Blog configuration files uninstalled.', ), new DirDelete( dir: 'dir/to/store/views/blog/', description: 'Blog view files uninstalled.', ), ); } }
Actions
Callable
The CallableAction::class calls the specified callable on process.
use Tobento\Service\Migration\Action\CallableAction; use Tobento\Service\Migration\ActionFailedException; $action = new CallableAction( callable: function ($name) { // do something on process }, // you may set parameters passed to the callable: parameters: ['name' => 'value'], name: 'A unique name', // or null description: 'Some description.', // (optional) type: 'keyword', // (optional) ); // Get the callable: var_dump(is_callable($action->getCallable())); // bool(true) // Get the parameters: var_dump($action->getParameters()); // array(1) { ["name"]=> string(5) "value" } var_dump($action->description()); // string(17) "Some description." var_dump($action->type()); // string(7) "keyword"
Dir Copy
Use the DirCopy::class action to copy a directory to another destination.
use Tobento\Service\Migration\Action\DirCopy; $action = new DirCopy( dir: 'dir/blog/views/', destDir: 'dir/to/store/views/blog/', overwrite: true, // if to overwrite existing dir (default true) name: 'A unique name', // or null description: 'Blog view files installed.', type: 'keyword', // (optional) ); var_dump($action->getDir()); // string(15) "dir/blog/views/" var_dump($action->getDestDir()); // string(24) "dir/to/store/views/blog/" var_dump($action->description()); // string(26) "Blog view files installed." var_dump($action->type()); // string(7) "keyword"
Dir Delete
Use the DirDelete::class action to delete a directory.
use Tobento\Service\Migration\Action\DirDelete; $action = new DirDelete( dir: 'dir/to/store/views/blog/', name: 'A unique name', // or null description: 'Blog view files uninstalled.', type: 'keyword', // (optional) ); var_dump($action->getDir()); // string(24) "dir/to/store/views/blog/" var_dump($action->description()); // string(28) "Blog view files uninstalled." var_dump($action->type()); // string(7) "keyword"
Fail
The Fail::class does always fail on action process, throwing a ActionFailedException::class, which might be useful in some cases.
use Tobento\Service\Migration\Action\Fail; use Tobento\Service\Migration\ActionFailedException; $action = new Fail( failMessage: 'message', name: 'A unique name', // or null description: 'Some description.', // (optional) type: 'keyword', // (optional) ); $action->process(); // throws ActionFailedException with the specified fail message.
Files Copy
Use the FilesCopy::class action to copy files to another directory.
use Tobento\Service\Migration\Action\FilesCopy; $action = new FilesCopy( files: [ 'dir/to/store/config/' => [ 'dir/blog/config/blog.php', ], ], overwrite: true, // if to overwrite existing files (default true) name: 'A unique name', // or null description: 'Blog configuration files installed.', type: 'keyword', // (optional) ); var_dump($action->getFiles()); // array(1) { ["dir/to/store/config/"]=> array(1) { [0]=> string(24) "dir/blog/config/blog.php" } } // only available after processing the action. var_dump($action->getCopiedFiles()); // array(0) { } // only available after processing the action. var_dump($action->getSkippedFiles()); // array(0) { } var_dump($action->description()); // string(35) "Blog configuration files installed." var_dump($action->type()); // string(7) "keyword"
Files Delete
Use the FilesDelete::class action to delete files.
use Tobento\Service\Migration\Action\FilesDelete; $action = new FilesDelete( files: [ 'dir/to/store/config/' => [ 'blog.php', ], ], name: 'A unique name', // or null description: 'Blog configuration files uninstalled.', type: 'keyword', // (optional) ); var_dump($action->getFiles()); // array(1) { ["dir/to/store/config/"]=> array(1) { [0]=> string(8) "blog.php" } } // only available after processing the action. var_dump($action->getDeletedFiles()); // array(0) { } var_dump($action->description()); // string(37) "Blog configuration files uninstalled." var_dump($action->type()); // string(7) "keyword"
File String Replacer
Use the FileStringReplacer::class to replace strings from a file.
use Tobento\Service\Migration\Action\FileStringReplacer; $action = new FileStringReplacer( file: 'dir/config/http.php', replace: [ '{key1}' => 'value1', '{key2}' => 'value2', ], name: 'A unique name', // or null description: 'Strings replaced.', type: 'keyword', // (optional) ); var_dump($action->getFile()); // string(19) "dir/config/http.php" var_dump($action->getReplace()); // array(2) { ["{key1}"]=> string(6) "value1" ["{key2}"]=> string(6) "value2" } var_dump($action->description()); // string(17) "Strings replaced." var_dump($action->type()); // string(7) "keyword"
Null
The NullAction::class does nothing at all, which might be useful in some cases.
use Tobento\Service\Migration\Action\NullAction; $action = new NullAction( name: 'A unique name', // or null description: 'Some description.', // (optional) type: 'keyword', // (optional) );
PDO Exec
Use the PdoExec::class to execute pdo statements.
use Tobento\Service\Migration\Action\PdoExec; $action = new PdoExec( pdo: $pdo, statements: [ "CREATE TABLE IF NOT EXISTS blog ( id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, active tinyint(1) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci AUTO_INCREMENT=0", ], name: 'A unique name', // or null description: 'Blog database tables installed.', type: 'keyword', // (optional) ); var_dump($action->getStatements()); // array var_dump($action->description()); // string(31) "Blog database tables installed." var_dump($action->type()); // string(7) "keyword"
Custom Actions
Below is an example of writing a custom action.
use Tobento\Service\Migration\ActionInterface; use Tobento\Service\Migration\ActionFailedException; class CustomAction implements ActionInterface { /** * Process the action. * * @return void * @throws ActionFailedException */ public function process(): void { // process the action } /** * Returns a name of the action. * * @return string */ public function name(): string { return $this::class; } /** * Returns a description of the action. * * @return string */ public function description(): string { return 'Action Description'; } /** * Returns the type of the action. * * @return string */ public function type(): string { return 'keyword'; } /** * Returns the processed data information. * * @return array<array-key, string> */ public function processedDataInfo(): array { return []; } }
Process Actions
You might process an action without using the migrator.
use Tobento\Service\Migration\Action\DirCopy; use Tobento\Service\Migration\ActionFailedException; $action = new DirCopy( dir: 'dir/blog/views/', destDir: 'dir/to/store/views/blog/', description: 'Blog view files installed.', ); try { $action->process(); } catch (ActionFailedException $e) { // Handle exception. }
Migrator
Create Migrator
use Tobento\Service\Migration\Migrator; use Tobento\Service\Migration\MigratorInterface; use Tobento\Service\Migration\AutowiringMigrationFactory; use Tobento\Service\Migration\MigrationJsonFileRepository; use Tobento\Service\Container\Container; // Any PSR-11 container $container = new Container(); // Create migrator. $migrator = new Migrator( new AutowiringMigrationFactory($container), new MigrationJsonFileRepository('private/dir/migrations/'), ); var_dump($migrator instanceof MigratorInterface); // bool(true)
Install Migration
use Tobento\Service\Migration\MigrationResultInterface; use Tobento\Service\Migration\MigrationInstallException; try { $result = $migrator->install(AnyMigration::class); var_dump($result instanceof MigrationResultInterface); // bool(true) } catch (MigrationInstallException $e) { // Handle exception. }
You might want to uninstall if the install has failed.
use Tobento\Service\Migration\MigrationResultInterface; use Tobento\Service\Migration\MigrationInstallException; use Tobento\Service\Migration\MigrationUninstallException; try { $result = $migrator->install(AnyMigration::class); } catch (MigrationInstallException $e) { try { $result = $migrator->uninstall(AnyMigration::class); } catch (MigrationUninstallException $e) { // Handle exception. } }
Uninstall Migration
use Tobento\Service\Migration\MigrationResultInterface; use Tobento\Service\Migration\MigrationUninstallException; try { $result = $migrator->uninstall(AnyMigration::class); var_dump($result instanceof MigrationResultInterface); // bool(true) } catch (MigrationUninstallException $e) { // Handle exception. }
You might want to uninstall only if the migration has been installed before.
use Tobento\Service\Migration\MigrationResultInterface; use Tobento\Service\Migration\MigrationUninstallException; if ($migrator->isInstalled(\App\Blog\AnyMigration::class)) { try { $result = $migrator->uninstall(AnyMigration::class); } catch (MigrationUninstallException $e) { // Handle exception. } }
Get Installed Migrations
$migrations = $migrator->getInstalled(); // get only from specific. $migrations = $migrator->getInstalled(namespace: 'App\Blog\');
Migration Result
The migrator install and uninstall method returns the migration result object on success:
use Tobento\Service\Migration\MigrationResultInterface; use Tobento\Service\Migration\MigrationInterface; $result = $migrator->install(AnyMigration::class); var_dump($result instanceof MigrationResultInterface); // bool(true) $result = $migrator->uninstall(AnyMigration::class); var_dump($result instanceof MigrationResultInterface); // bool(true)
Get the migration processed
use Tobento\Service\Migration\MigrationInterface; // Get the migration processed: var_dump($result->migration() instanceof MigrationInterface); // bool(true)
Get the migration actions processed
use Tobento\Service\Migration\ActionsInterface; // Get the migration actions processed: var_dump($result->actions() instanceof ActionsInterface); // bool(true) // You might want to iterate over the actions. foreach($result->actions() as $action) { $description = $action->description(); }
Migration Results
You might want to store your results as to get it later to show the migrations processed.
use Tobento\Service\Migration\Migrator; use Tobento\Service\Migration\MigratorInterface; use Tobento\Service\Migration\AutowiringMigrationFactory; use Tobento\Service\Migration\MigrationJsonFileRepository; use Tobento\Service\Migration\MigrationInstallException; use Tobento\Service\Migration\MigrationResults; use Tobento\Service\Migration\MigrationResultsInterface; use Tobento\Service\Migration\MigrationResults; use Tobento\Service\Container\Container; // Any PSR-11 container $container = new Container(); // Create migrator. $migrator = new Migrator( new AutowiringMigrationFactory($container), new MigrationJsonFileRepository('private/dir/migrations/'), ); // MigrationResults implementation. $container->set(MigrationResultsInterface::class, function() { return new MigrationResults(); }); try { $result = $migrator->install(AnyMigration::class); // Add result. $container->get(MigrationResultsInterface::class)->add($result); } catch (MigrationInstallException $e) { // Handle exception. } // Somewhere later, do something with the results. $results = $container->get(MigrationResultsInterface::class)->all();
Credits
tobento/service-migration 适用场景与选型建议
tobento/service-migration 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 345 次下载、GitHub Stars 达 0, 最近一次更新时间为 2021 年 10 月 20 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「package」 「migration」 「install」 「uninstall」 「tobento」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 tobento/service-migration 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 tobento/service-migration 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 tobento/service-migration 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Install Plugin for NetCommons3
Lets you add foreign keys in a swift! Foreign key adder in laravel migration.
Composer plugin for running post-install/post-update scripts of your project's dependencies
Manage PostgreSQL schemas in Laravel applications
Arikam CMS installers
统计信息
- 总下载量: 345
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 20
- 依赖项目数: 6
- 推荐数: 3
其他信息
- 授权协议: MIT
- 更新时间: 2021-10-20