Forum guided project

MySQL And Production

Step 13 / 13 Beginner to intermediate SQLite to MySQL path

MySQL And Production

The guided project starts with SQLite because it is simple to run locally. The same structure can move to MySQL when the app needs a server database, backups, multiple environments, or stronger operational tooling.

Goal

Move from local SQLite to a production-ready database without rewriting routes, controllers, views, or permission names.

What Stays The Same

  • Route structure
  • Controller action names
  • View structure
  • Repository public methods
  • Permission ability names
  • Admin middleware
  • API endpoint names

Keeping these stable is the point of the earlier SOLID boundaries.

What Changes

  • Database configuration points to MySQL.
  • Migration SQL uses MySQL column syntax.
  • Demo accounts become managed users.
  • Public demo read-only mode stays enabled only on the official documentation deployment.
  • Production writes always persist after validation and permission checks.

Step: Configure MySQL

DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=coriander_forum
DB_USER=forum_user
DB_PASSWORD=change-me
DB_CHARSET=utf8mb4

Create the database and user outside the app, then run:

php coriander migrate

Step: Adjust Migration Syntax

SQLite:

id INTEGER PRIMARY KEY AUTOINCREMENT
locked INTEGER NOT NULL DEFAULT 0
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP

MySQL:

id INT AUTO_INCREMENT PRIMARY KEY
locked TINYINT(1) NOT NULL DEFAULT 0
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP

Keep table names and column names the same so repositories barely change.

Step: Keep Writes In Services

Create one service per write action:

src/Modules/ForumDemo/Writes/ForumWriteService.php
src/Modules/ForumDemo/Writes/ModerationService.php
src/Modules/ForumDemo/Writes/UserRoleService.php

Each service should:

  • validate input
  • check permissions
  • write to the database with SQLManager::sqlScript() or the simple SQL helpers
  • return a predictable result array or object

Keep custom joins and writes inside repositories or services. Controllers should not contain SQL when moving from SQLite to MySQL.

Step: Add Production Rules

A real public forum needs more than role checks:

  • hashed passwords and account recovery
  • locked topics
  • deleted replies with audit records
  • rate limits for repeated posting
  • moderation queues for new accounts
  • backups and migration rollback testing

Checkpoint

After switching to MySQL, open the same URLs:

The app should feel the same from the route, controller, and view perspective.

Common Mistakes

  • Rewriting routes and views when only persistence changed.
  • Letting SQL details leak into controllers.
  • Disabling public demo protection on the official documentation site.

Next

You now have the full shape of a database-backed forum and a protected live documentation demo.

Live version

Open the safe demo

Use the demo when a guide step asks you to verify behavior. Local projects write to SQLite; this public demo validates writes without persisting visitor content.

Open forum demo

Project files

Download project files

This download does not include the CorianderPHP framework. Start from a CorianderPHP project, then use the completed app files as a reference.

Download completed app