Skip to main content

Loading migrations

Migrations are read through Flysystem, so they can live on the local disk or in any storage Flysystem supports, such as S3.

Finding migrations​

Dirthara\Migration\MigrationLoader::loadDirectory() loads the files of one directory whose name ends in .php. It does not look into subdirectories. A directory that does not exist loads nothing, the way Flysystem lists it. A failure to list a directory is an InvalidMigrationFileException with the directory in its context.

The migrator decides the order migrations run in; see running migrations.

Loading a file​

Dirthara\Migration\MigrationSourceLoader::loadFile() reads a file through Flysystem and requires it through a stream wrapper, so nothing is copied to a temporary file. The file must return an object implementing Dirthara\Migration\Contract\Migration; every load returns a new object.

A file that does not exist, cannot be read, does not compile, throws while loading, or returns something other than a migration fails with a Dirthara\Migration\Exception\InvalidMigrationFileException naming the file. Its message names only the file and, for a file that fails to load, the class of what it threw; the original failure, such as the ParseError with its line, is the exception's previous exception.

Paths inside a migration​

Inside a migration, __FILE__ and __DIR__ name the file by its stream-wrapper path, such as dirthara-migration://src/Users/Infrastructure/Migrations/2026_09_30_101500_create_users_table.php, and so do error messages and stack traces. A migration cannot reach files next to it through local paths.

While a migration loads, is_file(), file_exists(), and filesize() on its path report a regular, read-only file of its size. Once it has loaded, and for any other path on the scheme, they report no file, without a warning, so error handlers that inspect stack traces can check those paths safely.

The stream wrapper scheme​

The loader registers the dirthara-migration stream wrapper scheme the first time it loads a file. When another component has already registered that scheme, loading fails with a Dirthara\Migration\Exception\MigrationSourceLoaderException instead of loading migrations through a wrapper the package does not own. The other component's wrapper is left as it is.