1. Go to this page and download the library: Download woodholly/atk4-migrations library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
woodholly / atk4-migrations example snippets
use Atk4\Migrations\Model;
class Post extends Model
{
public $table = 'post';
protected function init(): void
{
parent::init();
// Indexes
$this->addField('title', ['index' => true]); // Regular index
$this->addField('slug', ['unique' => true]); // Unique index
$this->addIndex(['title', 'slug']); // Composite index
// Foreign keys (CASCADE, RESTRICT, SET NULL, NO ACTION, SET DEFAULT)
$this->hasOne('user_id', [
'model' => [User::class],
'onDelete' => 'CASCADE',
'index' => true, // FK + index
]);
// Composite foreign key
$this->addForeignKey(['product_id', 'warehouse_id'], [
'foreignTable' => 'inventory',
'foreignColumns' => ['product_id', 'warehouse_id'],
'onDelete' => 'RESTRICT',
]);
}
}
use Atk4\Data\Persistence;
return [
// Database connection
'persistence' => function () {
return new Persistence\Sql('mysql://user:pass@localhost/dbname');
},
// List of Model classes to track
'models' => [
\App\Model\User::class,
\App\Model\Post::class,
\App\Model\Comment::class,
],
// Where to store migration files (namespace => directory)
'migrations_paths' => [
'Database\\Migrations' => 'migrations', // Class namespace => filesystem path
],
];
// migrations/Version20250116120000.php
public function up(Schema $schema): void
{
// $this->addSql('DROP TABLE old_users');
// $this->addSql('CREATE TABLE users (...)');
$schema->renameTable('old_users', 'users');
}
public function down(Schema $schema): void
{
$schema->renameTable('users', 'old_users');
}
declare(strict_types=1);
use Atk4\Data\Persistence;
// Helper function to discover models from src/Model directory
function discoverModels(string $directory, string $namespace): array
{
$models = [];
$files = glob($directory . '/*.php');
foreach ($files as $file) {
$className = $namespace . '\\' . basename($file, '.php');
// Try to load the file first
if (!class_exists($className)) {
ons' => 'migrations',
],
];
use Atk4\Data\Persistence;
return [
// Required: Database connection
'persistence' => function () {
return new Persistence\Sql('mysql://user:pass@localhost/dbname');
},
// Required: Models to track
'models' => [
\App\Model\User::class,
\App\Model\Post::class,
],
// Optional: Migration history tracking table (defaults shown)
'table_storage' => [
'table_name' => 'doctrine_migration_versions', // Table that tracks executed migrations
'version_column_name' => 'version', // Column storing migration version numbers
],
// Optional: Where migrations are stored (namespace => directory path)
// Key = PHP namespace for migration classes
// Value = filesystem directory where migration files are created
'migrations_paths' => [
'Database\\Migrations' => 'migrations',
],
// Optional: Wrap all migrations in transaction
'all_or_nothing' => true,
// Optional: Each migration in its own transaction
'transactional' => true,
];
bash
# Option 1: Mark as not-executed (without running rollback SQL)
vendor/bin/migrations-cli.php version Version20250116120000 --delete
rm migrations/Version20250116120000.php
# Option 2: Actually rollback the database changes
vendor/bin/migrations-cli.php migrate prev # Rollback SQL is executed
rm migrations/Version20250116120000.php
bash
# Fix the error in your model
# Then generate a new migration that will fix the database
vendor/bin/migrations-cli.php diff
vendor/bin/migrations-cli.php migrate --dry-run -vv # Verify it fixes the issue
vendor/bin/migrations-cli.php migrate