Vibe Coding a Full-Stack PHP Community Platform

by mobes December 25, 2025 5 views

How I built and deployed a complete forum and article platform in a single session using AI-assisted development


What is Vibe Coding?


Vibe coding is a development approach where you collaborate with AI to build software through natural conversation. Instead of writing every line manually, you describe what you want, iterate on the results, and guide the AI toward your vision. It's not about replacing programming skills—it's about amplifying them.

Think of it like pair programming with a tireless partner who knows every framework, remembers every syntax quirk, and never gets frustrated when you change your mind for the fifth time.


The Project: A Developer Community Platform


I set out to build a community site with:

User authentication (registration, login, password reset)

A forum with categories, threads, and replies

An articles section with voting and moderation

A glassmorphic UI with an animated starfield background

Admin dashboard for content moderation

API endpoints for external publishing


The stack: PHP 8, MySQL, Tailwind CSS—no frameworks, just clean procedural code that any PHP developer can understand and modify.


The Development Pattern: Build, Test, Fix, Repeat


Here's the actual workflow we used to build this site:

Phase 1: Docker-First Local Development


We started with a Docker Compose setup for instant local development:

services:
web:
build: ./docker
ports:
- "8080:80"
volumes:
- ./public_html:/var/www/public_html
- ./src:/var/www/src
- ./vendor:/var/www/vendor
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: vibe9
MYSQL_ROOT_PASSWORD: dev_password


One docker-compose up and we had PHP 8, MySQL 8, and Apache running. No local PHP installation required. No XAMPP configuration headaches.

Phase 2: Schema-First Database Design


Before writing any PHP, we designed the complete database schema:

-- 11 tables covering all features
CREATE TABLE users (...);
CREATE TABLE sessions (...);
CREATE TABLE articles (...);
CREATE TABLE article_votes (...);
CREATE TABLE forum_categories (...);
CREATE TABLE forum_threads (...);
CREATE TABLE forum_posts (...);
-- Plus password resets, email verification, reactions


This upfront investment paid off immediately. No migrations, no schema changes mid-development. The AI generated the complete schema based on feature requirements, and we refined it once.

Phase 3: Feature-by-Feature Implementation


We built each feature as a complete vertical slice:

Authentication Flow:

1.Registration form with validation

2.Password hashing with bcrypt (cost factor 12)

3.Session management with secure cookies

4.CSRF tokens on every form

5.Login/logout with redirect handling


Forum System:

1.Categories with icons and ordering

2.Thread creation with slug generation

3.Reply system with post counts

4.View counting and timestamps

5.Pinning and locking for moderation


Articles Platform:

1.Markdown editor with preview

2.Draft/pending/published workflow

3.Admin approval system

4.Upvote/downvote with score calculation

5.View tracking


Each feature was complete before moving to the next. No half-finished code sitting around.

Phase 4: Real-Time Bug Fixing


When something broke, we fixed it immediately:

> "The forum thread creation is failing silently"

Investigation revealed the forum_threads table didn't have a content column—content belongs in forum_posts. We:

1.Identified the schema mismatch

2.Updated the INSERT to use a transaction

3.Created the thread first, then the first post

4.Added rollback on failure

$db->beginTransaction();
// Insert thread without content
$stmt->execute([$categoryId, $userId, $title, $slug]);
$threadId = $db->lastInsertId();
// Insert first post with content
$stmt->execute([$threadId, $userId, $content]);
$db->commit();


This pattern—immediate investigation and fix—kept momentum high.

Phase 5: Progressive Enhancement


Once core features worked, we enhanced:

Markdown Rendering:
Started with basic HTML escaping, then added:

Header parsing (# ## ###)

Bold text (**)

Code blocks with syntax highlighting styles

Inline code with neon styling

Lists (bulleted and numbered)

Mermaid diagram support for technical content


UI Polish:

Glassmorphic cards with backdrop blur

Animated starfield background (canvas-based)

Responsive navigation

Loading states and error messages

Color-coded user roles (admin = purple, mod = green)


The Shipping Pattern: Local to Production

Step 1: Build Assets Locally


Tailwind CSS requires compilation. We ran:

npm install
npm run build


This generates the minified styles.css from the Tailwind directives. The built CSS goes into version control—no build step needed on the server.

Step 2: Environment Configuration


We created a .env.production template:

DB_HOST=localhost
DB_NAME=your_production_db
DB_USER=your_db_user
DB_PASSWORD=CHANGE_ME

SITE_URL=https://yourdomain.com
DEBUG_MODE=false
DISPLAY_ERRORS=false


The config.php loads environment variables and falls back to sensible defaults. Same code, different environment.

Step 3: Database Migration


One SQL file with the complete schema:

DROP IF EXISTS for clean re-runs

CREATE TABLE for all 11 tables

INSERT for default data (forum categories)


Import via phpMyAdmin: upload file, click execute, done.

Step 4: File Upload Strategy


For Hostinger shared hosting, we used the File Manager:

Server Structure:
/home/username/
├── public_html/ ← Web root (upload site files here)
├── src/ ← Protected (outside web root)
├── vendor/ ← Composer packages (outside web root)
└── .env ← Credentials (outside web root)


Critical insight: Keeping src/, vendor/, and .env outside public_html means they're not web-accessible. PHP can still include them, but browsers can't download them.

Step 5: Permission Configuration


Only one folder needs write permissions:

public_html/assets/uploads/ → 755


Everything else stays read-only. Minimal attack surface.

Step 6: First-Run Setup


The setup wizard (/setup.php) handles initial configuration:

1.Checks if admin exists

2.Creates admin account with secure password

3.Writes .setup_complete lock file

4.Redirects to login


After setup completes, the wizard becomes inaccessible. No manual database inserts required.


The Debugging Pattern: When Things Go Wrong

Error 1: "Failed to create thread"


Symptom: Form submitted, generic error displayed, no thread created.

Investigation: Checked the schema—forum_threads has no content column. The INSERT was trying to write content to a non-existent column.

Fix: Restructured to use transactions. Thread goes in forum_threads, content goes in forum_posts as the first post.

Error 2: Markdown not rendering


Symptom: Raw markdown displayed with whitespace-pre-wrap instead of formatted HTML.

Investigation: The template was using e($post['content']) which escapes HTML. We needed a markdown-to-HTML converter.

Fix: Created formatMarkdown() function with regex replacements for common patterns. Applied before output, after escaping the raw input.

Error 3: View count wrong column


Symptom: Error on thread view page.

Investigation: Code referenced views but schema has view_count.

Fix: Updated all references to use the correct column name.

Pattern: Schema is truth. When in doubt, check the SQL.


What We Shipped


A complete community platform with:

Authentication: Registration, login, logout, password reset, email verification ready

Forum: 5 categories, threaded discussions, post counts, view tracking

Articles: Full publishing workflow, voting, admin moderation

Admin Dashboard: User management, content moderation, statistics

API: External publishing endpoint for Claude Code integration

UI: Glassmorphic design, animated background, responsive layout


All running on a $3/month shared hosting plan.


Lessons for Your Next Vibe Coding Session

1. Start with the Database


Design your schema before writing application code. It forces you to think through relationships and prevents mid-project migrations.

2. Build Complete Slices


Don't half-finish features. Get authentication working end-to-end before starting the forum. Complete the forum before adding articles.

3. Fix Bugs Immediately


When something breaks, stop and fix it. Accumulated bugs become archaeology projects. Fresh bugs have context.

4. Environment Variables Are Non-Negotiable


Never hardcode credentials. Use .env files locally and in production. Same code, different config.

5. Build Before Deploy


Compile your CSS, minimize your JS, run your tests—all locally. The server should just serve files, not build them.

6. Protect Your Source


Keep application code outside the web root when possible. If someone misconfigures the server, your PHP files won't be downloadable.

7. Document the Deployment


Write down the exact steps while they're fresh. Future you will thank present you.


The Vibe Coding Advantage


Traditional development: weeks of planning, days of setup, hours of configuration, then maybe some actual coding.

Vibe coding: describe what you want, iterate on results, ship something real in a single session.

The tools exist. The patterns work. The only question is what you're going to build.



*This article documents the actual development of Vibe9.net—built and deployed using the patterns described above.*

0

Log in to vote

No comments yet. Be the first to share your thoughts!

Log in to participate