Database Migrations
S-PHP includes a simple yet powerful migration system for managing database schema changes. Migrations are timestamped SQL files that run in order and track execution status.Creating Migrations
Generate a new migration file:Example
app/database/20260303141530_create_users_table.sql
Migration Naming
Migration files follow a timestamped naming convention (Command.php:36):- YmdHis: Year, Month, Day, Hour, Minute, Second (e.g.,
20260303141530) - name: Your descriptive migration name (e.g.,
create_users_table)
Timestamp Format
The 14-digit timestamp ensures migrations run in chronological order (init.php:40):- 2026 - Year
- 03 - Month
- 03 - Day
- 14 - Hour
- 15 - Minute
- 30 - Second
Writing Migrations
After generating a migration file, add your SQL code:Example: Create Table
Example: Alter Table
Example: Seed Data
Running Migrations
Execute all pending migrations:Migration Process
The migration system (init.php:8-91) performs these steps:-
Database Connection (init.php:19-23)
- Connects to MySQL using configuration from
.envfile - Creates database if it doesn’t exist
- Connects to MySQL using configuration from
-
Migrations Table (init.php:27-33)
- Creates
migrationstable to track executed migrations - Schema:
- Creates
-
File Discovery (init.php:35-41)
- Scans
app/database/for.sqlfiles - Only includes files starting with 14-digit timestamp
- Sorts files chronologically
- Scans
-
Execution (init.php:53-80)
- Checks which migrations have already run
- Skips previously executed migrations
- Runs new migrations in order
- Records execution in
migrationstable
Output Example
Skip Already Executed
Migration Status
Themigrations table tracks all executed migrations:
| id | migration | executed_at |
|---|---|---|
| 1 | 20260303141530_create_users_table.sql | 2026-03-03 14:15:45 |
| 2 | 20260303142015_add_user_profiles.sql | 2026-03-03 14:20:30 |
Database Configuration
Migrations use database settings from your.env file (init.php:12-16):
Best Practices
Naming Conventions
- Use descriptive names that explain what the migration does
- Use snake_case for migration names
- Examples:
create_users_tableadd_email_to_userscreate_posts_and_comments_tables
Migration Content
- Use IF EXISTS/IF NOT EXISTS to make migrations idempotent when possible
- One logical change per migration - don’t combine unrelated changes
- Include comments to explain complex operations
- Test migrations on a development database before production
SQL Guidelines
Empty Migrations
The system automatically skips empty migration files (init.php:67-70):Error Handling
Connection Errors
.env database credentials
Syntax Errors
File Read Errors
Migration Workflow
Typical development workflow:-
Create migration:
-
Edit migration file:
-
Run migrations:
-
Verify changes:
Limitations
- No rollback: The system doesn’t support automatic migration rollback
- No dry-run: Migrations execute immediately without preview
- SQL only: Only
.sqlfiles are supported (no PHP-based migrations)
Manual Rollback
To reverse a migration manually:- Create a new migration with reverse operations
- Remove the entry from
migrationstable if needed - Run the new migration