โโโ โ โ โโโ โโโ โโโ โโโ โ โ โโโ โ โ โโโ โโ โ
โโโ โโโ โโโ โ โ โ โโโ โโโ โ โโโ โ โ โ โโ
โ โ โ โ โ โโโ โ โ โ โ โ โโโ โ โ
THE GREAT LANGUAGE MIGRATION ๐
PROCEDURAL โ MODERN | LAMP โ CLOUD | 2005 โ 2025
Welcome to the CityPulse Events migration lab โ a journey from the golden age of LAMP stacks to the modern Python cloud era! ๐
Remember when every app was a collection of .php files, MySQL credentials lived in config.php, and $_GET['id'] was how you grabbed parameters? ๐ This lab brings back that 2005 nostalgia, then shows you how to level up to modern Python with FastAPI/Flask, PostgreSQL, JWT auth, and Azure services! โก
You'll take a 10-year-old procedural PHP event ticketing platform (complete with MD5 passwords, SQL injection vulnerabilities, and a 2000-line functions.php file ๐ฑ) and transform it into a modern, secure, cloud-ready Python API with auto-generated documentation, async database access, and proper authentication!
Legacy Stack:
APACHE STARTING... ๐ฅ
MYSQL CONNECTED ๐ฌ
PHP PARSED <?php ๐
JQUERY LOADED $ ๐ซ
SESSION STARTED ๐ช
MD5 HASHED... (yikes) ๐
Target Stack:
PYTHON IMPORTED ๐
FASTAPI INITIALIZED โก
POSTGRESQL CONNECTED ๐
ASYNC ENABLED ๐
JWT AUTHENTICATED ๐
OPENAPI DOCUMENTED ๐
By the end of this lab, you'll master:
โ
PHP to Python Translation โ Convert procedural PHP code to modern Python OOP patterns
โ
Framework Migration โ Choose between FastAPI (async, modern) or Flask (classic, proven)
โ
Database Evolution โ Migrate MySQL to PostgreSQL with SQLAlchemy 2.0
โ
Security Remediation โ Replace MD5 passwords with bcrypt, fix SQL injection, implement JWT
โ
Payment Modernization โ Swap PayPal IPN for Stripe Checkout Sessions
โ
Cloud Services โ Integrate Azure Blob Storage, Communication Services, Container Apps
โ
API-First Development โ Build self-documenting REST APIs with OpenAPI/Swagger
โ
Async Patterns โ Adopt modern async/await for database and HTTP operations
Before starting your migration quest, ensure you have:
- ๐ Python 3.11+ โ The modern runtime
- ๐ Basic PHP Reading Knowledge โ You'll need to understand what you're migrating from
- ๐ณ Docker Desktop โ For running both legacy and modern apps
- โ๏ธ Azure Subscription โ For cloud deployment (free trial works!)
- ๐๏ธ Basic SQL Knowledge โ You'll be migrating databases
- ๐ค GitHub Copilot CLI โ Your AI coding assistant
Optional but Helpful:
- Nostalgia for the LAMP stack era ๐
- Experience with REST APIs and JSON
- Understanding of async/await concepts
# For the authentic 2005 experience!
# Install XAMPP and drop the legacy folder into htdocs
# Navigate to http://localhost/citypulse
# But honestly, just use Docker ๐# Clone the repository
git clone https://github.com/EmeaAppGbb/appmodlab-php-legacy-to-python-flask-fastapi.git
cd appmodlab-php-legacy-to-python-flask-fastapi
# Start the legacy PHP app
git checkout legacy
docker-compose up -d
# Watch the magic!
# ๐ฅ Apache starting on port 8080
# ๐ฌ MySQL initializing on port 3306
# ๐ PHP 5.6 parsing your scripts
# Visit the legacy app
open http://localhost:8080# FastAPI version (primary)
git checkout solution
docker-compose up -d
# Flask alternative
git checkout solution-flask
docker-compose up -d
# Visit the API docs (FastAPI magic!)
open http://localhost:8000/docs
# Interactive Swagger UI appears! ๐โจcitypulse/ # The legacy codebase
โโโ ๐ index.php # Homepage with event listing
โโโ ๐ง config.php # Hardcoded credentials ๐ฌ
โโโ ๐ includes/
โ โโโ db.php # mysqli_connect() vibes
โ โโโ header.php # HTML fragments everywhere
โ โโโ footer.php # Copy-paste templating
โ โโโ functions.php # 2000 lines of globals ๐
โ โโโ auth.php # Session-based auth
โโโ ๐ events/
โ โโโ list.php # Event catalog
โ โโโ detail.php?id=X # SQL injection waiting to happen
โ โโโ create.php # Mixed HTML/PHP spaghetti
โ โโโ edit.php # More of the same
โ โโโ search.php # Raw SQL LIKE queries
โโโ ๐ tickets/
โ โโโ purchase.php # Ticket buying flow
โ โโโ checkout.php # PayPal IPN integration
โ โโโ confirm.php # Payment callback handler
โ โโโ my-tickets.php # User ticket history
โโโ ๐ organizers/
โ โโโ dashboard.php # Event organizer console
โ โโโ reports.php # HTML table reports
โ โโโ settings.php # Profile management
โโโ ๐ admin/
โ โโโ login.php # Admin authentication
โ โโโ events.php # Event moderation
โ โโโ users.php # User management
โโโ ๐ uploads/ # Filesystem uploads ๐
โโโ ๐ css/ # Stylesheets
โโโ ๐ js/ # jQuery 1.x scripts
โโโ .htaccess # Apache rewrite rules
citypulse_api/ # Clean Python architecture
โโโ ๐ pyproject.toml # Poetry dependency management
โโโ ๐ Dockerfile # Containerization
โโโ ๐ app/
โ โโโ ๐ฏ main.py # FastAPI application entry
โ โโโ ๐ api/
โ โ โโโ routes/ # API endpoint handlers
โ โ โ โโโ events.py # Event CRUD operations
โ โ โ โโโ tickets.py # Ticket purchase APIs
โ โ โ โโโ auth.py # JWT authentication
โ โ โ โโโ organizers.py # Organizer endpoints
โ โ โโโ dependencies.py # Dependency injection
โ โโโ ๐ core/
โ โ โโโ config.py # Environment-based config
โ โ โโโ security.py # JWT, bcrypt, OAuth2
โ โ โโโ database.py # Async SQLAlchemy setup
โ โโโ ๐ models/
โ โ โโโ event.py # SQLAlchemy models
โ โ โโโ ticket.py # Database models
โ โ โโโ user.py # Proper ORM
โ โโโ ๐ schemas/
โ โ โโโ event.py # Pydantic request/response
โ โ โโโ ticket.py # Type-safe schemas
โ โ โโโ user.py # Input validation
โ โโโ ๐ services/
โ โ โโโ event_service.py # Business logic layer
โ โ โโโ payment_service.py # Stripe integration
โ โ โโโ storage_service.py # Azure Blob Storage
โ โ โโโ email_service.py # Azure Communication Services
โ โโโ ๐ repositories/
โ โโโ event_repository.py # Data access layer
โ โโโ ticket_repository.py # Async database queries
โโโ ๐ tests/
โ โโโ test_events.py # Pytest test suite
โ โโโ test_auth.py # Authentication tests
โโโ ๐ migrations/
โโโ alembic/ # Database migrations
| Component | Technology | Status |
|---|---|---|
| Language | PHP 5.6 (procedural) | ๐ No namespaces, no Composer |
| Web Server | Apache + mod_php | ๐ฅ .htaccess magic |
| Database | MySQL 5.7 | ๐ฌ mysqli_connect() |
| Authentication | File-based sessions | ๐ช $_SESSION everywhere |
| Password Hash | MD5 | ๐ DANGER! |
| SQL Queries | String interpolation | ๐ SQL injection galore |
| Frontend | jQuery 1.x | ๐ซ $(document).ready() |
| Templating | PHP echo in HTML | ๐ Spaghetti code |
| PHPMailer (outdated) | ๐ง Copied into project | |
| Payments | PayPal IPN | ๐ณ No signature verification |
| File Uploads | move_uploaded_file() | ๐ No validation |
| Routing | .htaccess rewrites | ๐ Apache-dependent |
-- MySQL Schema (Legacy)
CREATE TABLE events (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
description TEXT,
venue_id INT,
organizer_id INT,
event_date DATE,
start_time TIME,
end_time TIME,
category VARCHAR(100),
max_capacity INT,
price DECIMAL(10,2),
status ENUM('draft','published','cancelled'),
image_path VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(255),
password VARCHAR(32), -- MD5 hash (32 chars) ๐ฑ
role ENUM('user','organizer','admin'),
name VARCHAR(255),
phone VARCHAR(20),
created_at TIMESTAMP
);
CREATE TABLE tickets (
id INT AUTO_INCREMENT PRIMARY KEY,
event_id INT,
user_id INT,
ticket_type VARCHAR(50),
price DECIMAL(10,2),
purchase_date TIMESTAMP,
payment_status ENUM('pending','completed','refunded'),
paypal_txn_id VARCHAR(100),
qr_code VARCHAR(255)
);<?php
// SQL Injection Paradise
$id = $_GET['id'];
$query = "SELECT * FROM events WHERE id = $id"; // ๐
// MD5 Password "Security"
$password = md5($_POST['password']); // ๐ Please don't
// Global State Everywhere
include 'includes/functions.php';
$user = get_current_user(); // From the global 2000-line file
// Mixed HTML and PHP
echo "<div class='event'>";
echo "<h2>" . $row['title'] . "</h2>"; // XSS waiting to happen
echo "</div>";
// Session Authentication
if ($_SESSION['logged_in'] != true) {
header('Location: login.php');
}
// Error Display in Production
ini_set('display_errors', 1); // Show all the secrets! ๐
?>| Component | Technology | Benefits |
|---|---|---|
| Language | Python 3.12 | ๐ Type hints, async/await, modern syntax |
| Framework | FastAPI / Flask | โก Auto docs, async support, dependency injection |
| ORM | SQLAlchemy 2.0 | ๐ฎ Async sessions, type-safe models |
| Database | PostgreSQL on Azure | ๐ JSONB, full-text search, cloud-managed |
| Auth | OAuth2 + JWT | ๐ Stateless, secure tokens |
| Password Hash | bcrypt via passlib | ๐ Industry standard, salted hashing |
| API Docs | OpenAPI/Swagger | ๐ Auto-generated, interactive |
| Validation | Pydantic | โ Type-safe request/response schemas |
| Azure Communication | ๐ง Cloud-native, scalable | |
| Payments | Stripe API | ๐ณ Modern, webhook-based |
| File Storage | Azure Blob Storage | โ๏ธ CDN-backed, geo-redundant |
| Hosting | Azure Container Apps | ๐ณ Serverless containers, auto-scale |
# Type-safe Pydantic models
from pydantic import BaseModel, EmailStr, validator
class EventCreate(BaseModel):
title: str
description: str
venue_id: int
event_date: date
max_capacity: int
price: Decimal
@validator('price')
def price_must_be_positive(cls, v):
if v < 0:
raise ValueError('Price must be positive')
return v
# Async database queries with SQLAlchemy
async def get_event(event_id: int, db: AsyncSession) -> Event:
stmt = select(Event).where(Event.id == event_id)
result = await db.execute(stmt)
return result.scalar_one_or_none()
# JWT Authentication with FastAPI Security
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)) -> User:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
user_id = payload.get("sub")
return await get_user_by_id(user_id)
# Dependency Injection
@router.post("/events", response_model=EventResponse)
async def create_event(
event: EventCreate,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user)
):
return await event_service.create(db, event, current_user)
# Auto-generated OpenAPI docs (FastAPI magic!)
app = FastAPI(
title="CityPulse Events API",
description="Modern event management platform",
version="2.0.0"
)
# Visit /docs for interactive Swagger UI! ๐# Start the legacy PHP application
git checkout legacy
docker-compose up -d
# ๐ฅ APACHE STARTING...
# ๐ฌ MYSQL CONNECTED...
# ๐ PHP PARSED <?php...
# Use GitHub Copilot CLI to explore
gh copilot suggest "show me the event detail page"
gh copilot suggest "find all SQL queries in the codebase"
gh copilot suggest "identify security vulnerabilities"Things to notice:
- ๐ SQL injection in
events/detail.php - ๐ MD5 passwords in
includes/auth.php - ๐ 2000-line
includes/functions.php - ๐ฏ No input validation anywhere
- ๐ File uploads with no security checks
# Switch to the database migration branch
git checkout step-1-database-migration
# Convert MySQL to PostgreSQL
gh copilot suggest "convert MySQL schema to PostgreSQL"
# Key changes:
# - AUTO_INCREMENT โ SERIAL
# - ENUM โ VARCHAR with CHECK constraints
# - TIMESTAMP โ TIMESTAMPTZ
# - Add proper indexes and foreign keysgit checkout step-2-api-layer
# Initialize Python project with Poetry
poetry init
poetry add fastapi uvicorn sqlalchemy asyncpg pydantic
# Create project structure
gh copilot suggest "create FastAPI project structure for event management"
# PYTHON IMPORTED ๐
# FASTAPI INITIALIZED โก# Translate PHP endpoints to FastAPI routes
gh copilot suggest "convert events/list.php to FastAPI endpoint"
gh copilot suggest "create Pydantic schemas for event models"
# Watch OpenAPI docs auto-generate!
# Visit http://localhost:8000/docsgit checkout step-3-auth-and-security
# Replace sessions with JWT
gh copilot suggest "implement JWT authentication with FastAPI"
gh copilot suggest "migrate MD5 passwords to bcrypt"
# JWT AUTHENTICATED ๐
# BCRYPT HASHED ๐git checkout step-4-payment-and-services
# Replace PayPal IPN with Stripe
gh copilot suggest "integrate Stripe Checkout for ticket purchases"
gh copilot suggest "set up Stripe webhook handler"
# STRIPE CONNECTED ๐ณ
# WEBHOOKS CONFIGURED ๐ช# Add cloud services
gh copilot suggest "integrate Azure Blob Storage for file uploads"
gh copilot suggest "set up Azure Communication Services for email"
# AZURE CONNECTED โ๏ธ
# BLOB STORAGE READY ๐ฆgit checkout step-5-deploy
# Containerize and deploy
gh copilot suggest "create Dockerfile for FastAPI app"
gh copilot suggest "deploy to Azure Container Apps"
# DOCKER BUILT ๐ณ
# AZURE DEPLOYED โ๏ธ
# LIVE IN PRODUCTION ๐Total Lab Time: 4โ6 hours
| Phase | Duration | What You'll Do |
|---|---|---|
| ๐ต๏ธ Legacy Exploration | 30 mins | Run PHP app, identify anti-patterns |
| ๐๏ธ Database Migration | 45 mins | MySQL โ PostgreSQL schema conversion |
| ๐ FastAPI Setup | 45 mins | Project structure, dependencies, ORM |
| ๐ค๏ธ API Development | 90 mins | Build routes, models, schemas |
| ๐ Auth & Security | 60 mins | JWT, bcrypt, input validation |
| ๐ณ Integrations | 60 mins | Stripe, Azure services |
| ๐ Deployment | 45 mins | Docker, Azure Container Apps |
| ๐งช Testing | 30 mins | Pytest, API testing |
- ๐ FastAPI Documentation โ Modern Python web framework
- ๐ Flask Documentation โ Classic Python web framework
- ๐ SQLAlchemy 2.0 โ Python SQL toolkit and ORM
- ๐ Pydantic โ Data validation using Python type hints
- ๐ Azure Container Apps โ Serverless containers
- ๐ PHP to Python Translation Guide
- ๐ Security Remediation Checklist
- โก FastAPI vs Flask Comparison
- ๐๏ธ MySQL to PostgreSQL Migration
- ๐ค GitHub Copilot CLI โ AI coding assistant
- ๐ณ Docker Desktop โ Containerization platform
- ๐ฎ Postman โ API testing (or use Swagger UI!)
- ๐งช pytest โ Python testing framework
Complete this lab to earn:
- โ LAMP Stack Archaeologist โ Successfully ran a legacy PHP application
- โ Python Modernizer โ Migrated procedural PHP to modern Python
- โ Security Fixer โ Remediated MD5 passwords and SQL injection
- โ API Architect โ Built auto-documented REST APIs
- โ Cloud Native Developer โ Deployed to Azure Container Apps
Found a bug? Want to improve the lab? Contributions welcome!
# Fork the repository
gh repo fork EmeaAppGbb/appmodlab-php-legacy-to-python-flask-fastapi
# Create a feature branch
git checkout -b feature/amazing-improvement
# Make your changes and commit
git commit -m "Add amazing improvement"
# Push and create a pull request
git push origin feature/amazing-improvement
gh pr createThis project is licensed under the MIT License โ see LICENSE for details.
Built with ๐ by the EmeaAppGbb Team
Special thanks to:
- The PHP community for building the web (circa 2005) ๐
- The Python community for modernizing it (2025 edition) ๐
- Everyone who survived the LAMP stack era ๐ฅ
- Developers who still maintain legacy PHP apps (you're heroes!) ๐ฆธ
โโโ โ โ โโโ โโ โ โโโ โ โ โโโ โ โ โโโ โโโ โโโ
โ โโโ โโโ โ โโ โ โ โโโ โ โ โ โ โโ โ โ โโโ
โ โ โ โ โ โ โ โ โ โ โโโ โโโ โ โโโ โ โ
โโโโโ โ โโโ โโโ โโโ โโโ โ โโ โ โโโ โ
โ โ โ โ โโโ โโโ โโโ โ โ โ โโ โโโ โ
Happy Migrating! May your SQL be parameterized and your passwords be hashed! ๐