Vanilla-PHP verstehen, bevor man migriert: funktionaler Projektsnapshot als Grundlage für Migration zu Symfony
Die Migration eines gewachsenen Vanilla-PHP-Projekts nach Symfony scheitert selten an Symfony selbst, sondern fast immer an unvollständigem Projektverständnis. Legacy-Code ist meist funktional, nicht objektorientiert, verteilt Logik über Includes, globale Zustände und implizite Konventionen. Ohne belastbaren Überblick wird jede „Vibe-Coding“-Migration zum Blindflug.
Der hier verwendete Prompt adressiert genau dieses Problem: Er erzeugt keinen Migrationscode, sondern einen funktionalen, semantischen Snapshot des gesamten Repositories. Dieser Snapshot dient ausschließlich als belastbarer Kontext für eine spätere, automatisierte oder halbautomatisierte Migration.
Ziel: Analyse statt Aktion
Der Prompt zwingt das Modell in die Rolle eines Software-Archäologen. Es wird ausdrücklich untersagt, Architekturvorschläge zu machen oder Code zu verändern. Stattdessen entsteht eine vollständige Bestandsaufnahme:
- vollständiger Repository-Baum
- klare Trennung zwischen analysierten und nur gelisteten Dateien
- systematische Zerlegung jeder relevanten Datei nach Verantwortung und Abhängigkeiten
Damit entsteht ein Zustand, den viele Projekte nie hatten: dokumentierte Realität statt implizitem Wissen.
Strikte Scope-Disziplin
Ein zentrales Problem bei automatisierten Analysen ist Scope-Drift. Der Prompt verhindert das durch klare Regeln:
- Tiefenanalyse nur für:
.php,.html/.htm,.js - CSS: nur Pfade, keine inhaltliche Analyse
- Assets & Sonstiges (Bilder, Fonts, Binaries, Vendor, Minified Files):
vollständig gelistet, aber explizit als nicht analysiert markiert
Das Ergebnis ist vollständig, ohne unnötig Ressourcen auf irrelevante Dateien zu verschwenden.
Was der Prompt tatsächlich liefert
Der Output ist ein strukturierter Markdown-Bericht mit drei klaren Ebenen:
A) Repository-Tree (vollständig)
- Jeder Ordner und jede Datei wird erfasst
- Jede Datei ist eindeutig gekennzeichnet:
[ANALYZED][CSS-LISTED][LISTED-ONLY]
Damit existiert erstmals eine vollständige Inventarliste des Projekts.
B) Detaillierte Dateinotizen (nur analysierte Dateien)
Für jede relevante Datei:
- Dateipfad
- Dateiverantwortung (kompakt, präzise)
- Funktionen / Einheiten
- Zweck
- Ein- und Ausgaben
- Nutzung von Globals/Superglobals
- Side Effects (DB, FS, Sessions, Header, Mail, HTTP)
- Abhängigkeiten
- bekannte Call-Sites
HTML-Dateien werden nach Seitenlogik, Formularen und Script-Abhängigkeiten beschrieben.
JavaScript nach Events, Netzwerkzugriffen und DOM-Kopplung.
Das Ergebnis ist keine bloße Beschreibung, sondern eine funktionsorientierte Landkarte.
C) Architektur-Zusammenfassung
Kurz und nüchtern:
- Einstiegspunkte (Web, CLI)
- Routing-Mechaniken
- Include-/Require-Strukturen
- zentrale Querschnittsmodule
- kritischste Dateien im Gesamtsystem
Diese Zusammenfassung ist der Brückenkopf zur späteren Symfony-Architektur.
Warum das ideal für Vibe-Coding ist
„Vibe Coding“ funktioniert nur, wenn das Modell den Ist-Zustand vollständig kennt. Dieser Prompt erzeugt:
- einen stabilen Kontext
- reproduzierbare Analyse
- keine Vermischung von Analyse und Design
Damit lassen sich anschließend gezielt Prompts formulieren wie:
- „Mappe diese Funktionen auf Symfony-Controller“
- „Ersetze globale DB-Zugriffe durch Doctrine“
- „Baue aus diesen Entry-Points ein Front-Controller-Routing“
Ohne zuvor Annahmen treffen zu müssen.
Der verwendete Prompt
Act like a senior software archaeologist and codebase cartographer specializing in legacy, functional (non-OOP) vanilla PHP repositories.
Your objective: produce a complete, accurate, repo-wide “project map” that I can use as migration context for moving this codebase to Symfony. You must NOT propose or implement the migration now—only analyze and document the current repo.
Scope rules (IMPORTANT):
- Analyze ONLY these file types in depth: .php, .html/.htm, .js
- Do NOT analyze: images (.jpg/.jpeg/.png/.gif/.webp/.svg/.ico), media, fonts, binaries, vendor bundles, minified artifacts (e.g., *.min.js) unless they are the only source.
- CSS: do NOT analyze CSS contents; only list the CSS file paths in the tree (no responsibility/function breakdown).
- Still list all files/folders in the repository tree, but mark non-analyzed file types as “Listed only (not analyzed)”.
Task (do this end-to-end):
1) Enumerate the full repository tree (all folders/files, including configs, hidden files, entrypoints, scripts, cron jobs, SQL dumps, templates, assets, and docs).
2) Read and analyze EVERY relevant file (.php, .html/.htm, .js) and determine what it does.
3) For EVERY PHP file:
- Extract every function (including helpers) and summarize:
- Purpose (what it does)
- Inputs/outputs (params, return values; mention globals/superglobals used)
- Side effects (DB, filesystem, sessions/cookies, headers, email, external HTTP calls)
- Key dependencies (includes/requires, shared globals/constants, referenced modules)
- Important call sites (who calls it / where it is used, if detectable)
4) For EVERY HTML file:
- Summarize the page/template responsibility, dynamic placeholders (if any), forms, and referenced scripts/styles.
5) For EVERY JS file:
- Summarize major responsibilities, exported APIs, event bindings, network calls (fetch/XHR), DOM dependencies, and coupling to specific pages/templates.
6) Identify cross-file structure across the analyzed files:
- Main entrypoints (web/CLI), routing mechanisms (front controller patterns, switch-based routers), include/require chains
- Shared modules (DB access, auth/session, templating, utilities, validation, logging)
7) If a file’s purpose is unclear, infer cautiously from usage and name, and label it “uncertain” with the best evidence (who includes it / where referenced).
Output format (Markdown):
A) Repository Tree (full coverage):
- Show a directory tree where each leaf is a file node.
- For each file node, include a short tag:
- [ANALYZED] for .php/.html/.htm/.js
- [CSS-LISTED] for .css
- [LISTED-ONLY] for everything else (including images)
B) Detailed File Notes (ONLY for analyzed files):
For each analyzed file, include exactly:
1. Path/filename
2. File responsibility (1–3 sentences)
3. Functions/units:
- For PHP: list each function as:
- functionName(): purpose + key I/O + side effects + dependencies + where used (if detectable)
- For JS: list key functions/modules/exports similarly (no need to document every tiny helper if it’s purely trivial; prioritize meaningful units)
- For HTML: list key sections/forms/scripts it depends on
C) Architecture Summary (short):
- Top-level layers/modules, core request flows, and the 5–10 most critical entrypoints/files among the analyzed set.
Quality rules:
- No skipped relevant files (.php/.html/.htm/.js). No placeholders.
- Be concise but complete; prefer tight bullets over long prose.
- Explicitly confirm at the end:
- Count of analyzed files by type (PHP/HTML/JS)
- Count of CSS files listed
- Count of listed-only files (non-analyzed)
- That every PHP function across analyzed PHP files is documented.
Take a deep breath and work on this problem step-by-step.
Zwischenschritt
Dieser Prompt ist kein Migrationstool, sondern ein Voraussetzungserzeuger. Er ersetzt kein technisches Design, sondern schafft die Grundlage dafür. Wer Vanilla-PHP ernsthaft nach Symfony überführen will, benötigt zuerst einen solchen funktionalen Snapshot. Alles andere ist Raten.
Ergänzung des bestehenden Artikels (inhaltlich anschließen, sachlich, ohne Stilbruch):
Vom Projektsnapshot zur Migration: Startpunkt für Vibe Coding
Der zuvor beschriebene Analyse-Prompt endet bewusst vor jeder Code-Veränderung. Sein Ergebnis (PROJECT_MAP.md) ist ein funktionaler, semantischer Ist-Zustand des Repositories. Genau dieses Artefakt ist der Schlüssel, um im nächsten Schritt kontrolliert in das eigentliche Vibe Coding einzusteigen.
Entscheidend ist:
Vibe Coding startet nicht aus dem Bauch heraus und nicht aus dem Quellcode allein, sondern aus einer expliziten, maschinenlesbaren Beschreibung der bestehenden Anwendung.
Rolle des zweiten Prompts
Der folgende Prompt setzt genau hier an. Er definiert das Modell explizit als Migration Lead und zwingt es, PROJECT_MAP.md als Single Source of Truth zu verwenden. Damit wird verhindert, dass:
- Funktionen übersehen werden
- implizite Entry-Points verloren gehen
- Includes/Side-Effects falsch aufgelöst werden
- oder eine „Big-Bang“-Neuentwicklung entsteht
Der Prompt startet keine abstrakte Refaktorierung, sondern eine schrittweise, lauffähige Systemtransformation.
Der Vibe-Coding-Migrationsprompt
Act like a Staff Software Engineer and migration lead who specializes in converting large legacy vanilla PHP (functional, no classes) systems into modern Symfony applications. You are operating as a Vibe Coding agent with full repository access, and you MUST use PROJECT_MAP.md as the primary source of truth about the current codebase structure, responsibilities, entrypoints, include chains, and functions.
Your objective: transform the entire repository from vanilla PHP into a working Symfony project while preserving behavior. This is a full migration, not a partial refactor. You must produce code changes (new Symfony structure + adapted code) and keep the application runnable throughout the process.
Inputs you must read first:
1) PROJECT_MAP.md (generated project map) — treat it as authoritative.
2) The actual repository source files — validate details against code when needed.
3) Any existing config/env examples (e.g., .env, config.php, README).
Migration strategy (follow strictly, step-by-step):
1) Baseline & Safety
- Identify and list all entrypoints from PROJECT_MAP.md (web and CLI).
- Add a minimal automated smoke test or script that can hit key entrypoints (HTTP + CLI) to verify before/after behavior.
- Ensure a repeatable local run procedure (document in MIGRATION_NOTES.md).
2) Create Symfony Skeleton
- Initialize Symfony structure (public/, src/, templates/, config/, migrations/, etc.).
- Configure environment, routing, controllers, Twig, Doctrine (only if DB is used), sessions, and logging.
- Keep the legacy app runnable in parallel during transition (e.g., legacy/ directory + “bridge” routing) until cutover.
3) Map Legacy Modules to Symfony Components
Using PROJECT_MAP.md, create a “Migration Matrix” table in MIGRATION_NOTES.md:
- Legacy file path -> Symfony destination (Controller/Service/Repository/Twig/Command/EventSubscriber/etc.)
- Legacy responsibility -> Symfony responsibility
- Key functions -> new class/method mapping
- Dependencies/includes -> Symfony DI/services configuration
- Data access -> Doctrine DBAL/ORM or a dedicated DB service (choose the smallest-change option first)
4) Incremental Cutover (vertical slices)
- Migrate one user-visible flow at a time (route/page/feature), prioritizing the most central entrypoints and shared modules identified in PROJECT_MAP.md.
- For each slice:
a) Create Symfony route + controller
b) Move logic into services (thin controllers)
c) Replace includes/requires with DI and explicit service calls
d) Convert HTML templates to Twig (keep markup as-is unless required)
e) Port relevant JS files into public/ assets unchanged (unless build tooling required)
f) Add/extend tests or smoke checks confirming identical behavior
- Maintain compatibility with sessions/cookies/auth flows; do not break URLs unless you add redirects.
5) Data Layer Migration
- If the legacy code uses raw SQL, wrap it first with a Symfony service using Doctrine DBAL (minimal change).
- Only introduce Doctrine ORM entities once behavior is stable and endpoints are migrated.
- Centralize connection handling, transactions, and error handling.
6) Auth, Security, and Globals
- Identify authentication/authorization from PROJECT_MAP.md and implement Symfony Security equivalents.
- Replace superglobal usage ($_GET/$_POST/$_SESSION/$_COOKIE) with Request/Session abstractions, but preserve behavior.
- Replace header/output side effects with Symfony Responses.
7) Final Cutover & Cleanup
- Once all routes/entrypoints are migrated, remove the legacy bridge.
- Ensure all features in PROJECT_MAP.md are accounted for and mapped.
- Run a final repo-wide search to confirm no remaining includes to legacy entry scripts and no direct output/exit usage where Symfony should handle responses.
Hard requirements:
- You MUST continuously reference PROJECT_MAP.md to decide what to migrate next and how modules connect.
- You MUST keep the application runnable after each major step (no “big bang” rewrite).
- Preserve existing URLs, query parameters, and response formats unless explicitly redirected.
- Do not drop features. If something is unclear, create a “Migration Question” item in MIGRATION_NOTES.md and proceed with a safe assumption.
- Output must include:
- Updated Symfony project code in-repo
- MIGRATION_NOTES.md with the Migration Matrix + decisions + remaining tasks
- A checklist showing every analyzed legacy file from PROJECT_MAP.md has a mapped Symfony destination and migration status.
Deliverables (files to create/update):
- MIGRATION_NOTES.md (matrix, progress, decisions, questions)
- Symfony codebase (src/, templates/, config/, public/, migrations/ as needed)
- Tests or smoke scripts (minimal but runnable)
- README_MIGRATION.md (how to run, how to validate, how to deploy)
Take a deep breath and work on this problem step-by-step.
Warum diese Kombination funktioniert
Erst Analyse-Prompt, dann Migrations-Prompt:
Diese Trennung ist der entscheidende Hebel.
PROJECT_MAP.mdfixiert den Ist-Zustand- der zweite Prompt erzwingt Disziplin, Reihenfolge und Rückverfolgbarkeit
- jede Migration ist nachvollziehbar, testbar und reversibel
Vibe Coding wird damit nicht kreativ-beliebig, sondern ingenieurmäßig steuerbar.
Der Roboter ist jetzt nicht mehr im Spaghetti-Chaos gefangen – er entwirrt es systematisch.
0 Kommentare