Ein Tutorial um eine Journaling App zu schreiben. PHP, SQLITE und einfach CSS und HTML.
  • PHP 61.5%
  • CSS 35.7%
  • Dockerfile 2.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-28 18:03:04 +02:00
kapitel-01 feat: add course chapters 1 and 2 with Docker setups, documentation, and PHP scripts 2026-09-26 15:16:13 +02:00
kapitel-02 Kapitel 1-3 didaktisch harmonisiert: Nahtlose Kontinuität, Partials & Clean UI 2026-09-27 00:59:04 +02:00
kapitel-03 Kapitel 1-3 didaktisch harmonisiert: Nahtlose Kontinuität, Partials & Clean UI 2026-09-27 00:59:04 +02:00
kapitel-04 Kapitel 4: SQLite-Verbindung & PDO-Grundlagen mit Helper-Funktion e() und XSS-Schutz 2026-09-27 14:02:33 +02:00
kapitel-05 feat: adjust chapter 5 again and removed the tags 2026-09-28 18:02:45 +02:00
kapitel-06 feat: add chapter 6 implementation and documentation for form processing and secure storage 2026-09-28 18:02:57 +02:00
01-die-docker-werkbank.md Kapitel 1-3 didaktisch harmonisiert: Nahtlose Kontinuität, Partials & Clean UI 2026-09-27 00:59:04 +02:00
02-php-basics-im-web.md Kapitel 1-3 didaktisch harmonisiert: Nahtlose Kontinuität, Partials & Clean UI 2026-09-27 00:59:04 +02:00
03-ui-layout-und-partials.md Kapitel 1-3 didaktisch harmonisiert: Nahtlose Kontinuität, Partials & Clean UI 2026-09-27 00:59:04 +02:00
04-sqlite-und-pdo-grundlagen.md Kapitel 4: SQLite-Verbindung & PDO-Grundlagen mit Helper-Funktion e() und XSS-Schutz 2026-09-27 14:02:33 +02:00
05-der-neuer-eintrag-dialog.md feat: adjust chapter 5 again and removed the tags 2026-09-28 18:02:45 +02:00
06-formularverarbeitung-und-sicheres-speichern.md feat: add chapter 6 implementation and documentation for form processing and secure storage 2026-09-28 18:02:57 +02:00
AGENTS.md docs: mark chapter 6 as complete and update course outline and agent guidelines 2026-09-28 18:03:04 +02:00
README.md docs: mark chapter 6 as complete and update course outline and agent guidelines 2026-09-28 18:03:04 +02:00
TODO.md docs: mark chapter 6 as complete and update course outline and agent guidelines 2026-09-28 18:03:04 +02:00

MyJournal — PHP & Docker Praxiskurs (DayOne-Style)

Ein modularer, praxisnaher Kurs in 20 Kapiteln. Lerne modernes PHP (8.2+) Schritt für Schritt von den Grundlagen bis zur fertigen Journal-App – ohne Framework-Magie, ohne npm-Ballast, direkt im Docker-Container mit SQLite und eigenem CSS.


🎯 Kursphilosophie & Didaktik (KISS)

  1. Kein Framework, echtes Handwerk: Wir nutzen Vanilla PHP und Standard-Funktionen (PDO, $_POST, $_SESSION, native Datumsfunktionen). Du lernst, wie das Web und PHP im Kern funktionieren.
  2. Sicherheit ab Tag 1, nicht als Nachgedanke: Prepared Statements gegen SQL-Injections und htmlspecialchars() gegen XSS werden nicht erst am Ende „nachgerüstet“, sondern von der ersten Datenbankabfrage und Formularausgabe an zur Selbstverständlichkeit.
  3. Erfolgserlebnis in jedem Kapitel: Jedes Kapitel liefert ein sofort im Browser sichtbares und testbares Ergebnis. Keine „Trockenübungen“ ohne UI-Bezug.
  4. Schrittweises Vorgehen: Wir erstellen Code erst, wenn das jeweilige Kapitel an der Reihe ist – kein voreiliges Generieren von 20 Dateien auf einmal.

🛠 Tech-Stack & Architektur

  • Laufzeitumgebung: Docker (offizielles php:8.2-apache Image) mit docker-compose
  • Datenbank: SQLite via PHP PDO (als Datei im Container gemountet – kein separater DB-Server nötig)
  • Code-Ablage: htdocs/ (Web-Root des Apache-Servers)
  • Frontend: Semantisches HTML5, Vanilla CSS (Mobile First, Flexbox/Grid, Dark/Light Touch), minimale Micro-Interactions
  • Architektur-Muster: Pragmatische Trennung: Controller/Logik oben, Rendering/Templates unten (partials/header.php, partials/footer.php), später kleine Helper-Funktionen.

📚 Die 20 Kapitel im Überblick

Phase 1: Fundament & Umgebung       (Kapitel 1 - 4)
  ├─ [Kapitel 1: Die Docker-Werkbank & Hello World](01-die-docker-werkbank.md) (Code: [kapitel-01/](kapitel-01/))
  ├─ [Kapitel 2: PHP Basics im Web (Arrays & Superglobals)](02-php-basics-im-web.md) (Code: [kapitel-02/](kapitel-02/))
  ├─ [Kapitel 3: Clean UI Skeleton & Partials](03-ui-layout-und-partials.md) (Code: [kapitel-03/](kapitel-03/))
  └─ [Kapitel 4: SQLite-Verbindung & PDO-Grundlagen](04-sqlite-und-pdo-grundlagen.md) (Code: [kapitel-04/](kapitel-04/))
Phase 2: Kern-Journal & DB (CRUD)   (Kapitel 5 - 11)
  ├─ [Kapitel 5: Der "Neuer Eintrag"-Dialog](05-der-neuer-eintrag-dialog.md) (Code: [kapitel-05/](kapitel-05/))
  └─ [Kapitel 6: Formularverarbeitung & Sicheres Speichern](06-formularverarbeitung-und-sicheres-speichern.md) (Code: [kapitel-06/](kapitel-06/))
Phase 3: DayOne Features            (Kapitel 12 - 15)
Phase 4: Medien & Feinschliff       (Kapitel 16 - 19)
Phase 5: Bonus (PWA & Offline)      (Kapitel 20)

Struktur dieses Buch-Repositories:

  • Kapitel (Markdown): Liegen direkt im Hauptverzeichnis (z. B. 01-die-docker-werkbank.md).
  • Begleitender Beispiel-Code: Liegt in entsprechenden Unterordnern (z. B. kapitel-01/).
  • Ziel: Reines Lehrmaterial zum Selbststudium und Nachschlagen. Du liest das Buch und programmierst in deinem eigenen Tempo.

Phase 1: Fundament & Umgebung

Kapitel 1: Die Docker-Werkbank einrichten

  • PHP / Web-Theorie: Wie arbeiten Webserver (Apache), PHP-Modul und Browser zusammen? Der HTTP-Request-Response-Zyklus.
  • Praxis:
    • Dockerfile erstellen (PHP Apache mit aktiviertem pdo_sqlite und mod_rewrite).
    • docker-compose.yml mit Port-Mapping (8080:80) und Volume-Mount für htdocs/.
    • Erstes index.php mit phpinfo() und "Hello World".
  • Ergebnis: Container startet mit docker compose up, http://localhost:8080 zeigt die funktionierende PHP-Umgebung.

Kapitel 2: PHP Basics im HTTP-Kontext

  • PHP-Theorie: Variablen, Datentypen, String-Interpolation, Arrays (indiziert & assoziativ).
  • Web-Theorie: Superglobals verstehen: $_SERVER, $_GET. Wie liest PHP Query-Parameter aus (?name=World)?
  • Praxis: Kleine dynamische Begrüßung und Ausgabe von Server-Infos (PHP-Version, Datum, Client-IP).
  • Ergebnis: Verständnis, wie PHP dynamischen HTML-Code zur Laufzeit zusammenbaut.

Kapitel 3: Clean UI Skeleton & Partials (Mobile First)

  • PHP-Theorie: Code-Wiederverwendung mit include, require, require_once. Der Unterschied und Best Practices.
  • HTML/CSS:
    • App-Layout mit Header, Top-Nav (Entries, New, On This Day, Search, Stats) und Content-Bereich.
    • CSS-Variablen für Farben, Typografie, Spacing, Card-Design im Stil von DayOne.
  • Praxis: Aufteilung in partials/header.php, partials/footer.php und partials/nav.php.
  • Ergebnis: Ein modernes, responsives Seitengerüst, das in allen Folgeseiten wiederverwendet wird.

Kapitel 4: SQLite-Verbindung & PDO-Grundlagen

  • PHP-Theorie: Was ist PDO (PHP Data Objects)? Exception Handling (try...catch), DSN-Verbindung.
  • Datenbank: Warum SQLite perfekt für Journaling ist. Anlegen der Datenbankdatei journal.db und Berechtigungen im Container.
  • Praxis:
    • Zentraler DB-Helper (db.php), der eine Singleton-PDO-Instanz bereitstellt.
    • Automatisches Erstellen der Tabelle entries beim ersten Start (Schema-Migration per SQL).
  • Ergebnis: Beim Aufruf prüft das Skript die DB, legt die Tabelle bei Bedarf an und bestätigt die Verbindung im UI.

Phase 2: Kern-Journal & Datenfluss (CRUD)

Kapitel 5: Der "Neuer Eintrag"-Dialog (HTML Form & Datums-Defaults)

  • PHP-Theorie: Arbeiten mit Datum und Uhrzeit in PHP (DateTimeImmutable, Formatierung Y-m-d\TH:i).
  • Praxis:
    • Formular aufbauen: Datum/Uhrzeit-Feld (vorausgefüllt mit aktuellem Zeitstempel).
    • Stimmungs-Auswahl (Mood): 6 definierte Zustände (z. B. Motiviert, Gemütlich, Nachdenklich, Begeistert, Müde, Traurig) mit Emojis.
    • Großes Textfeld für den Inhalt und Abbrechen-/Speichern-Aktionen.
  • Ergebnis: Ein fertiges Eingabeformular, das standardmäßig die aktuelle Uhrzeit vorschlägt.

Kapitel 6: Formularverarbeitung & Sicheres Speichern (Prepared Statements)

  • PHP-Theorie: $_POST, Formular-Validierung, Sanitisierung, POST-Redirect-GET-Pattern (PRG), um doppeltes Absenden bei F5 zu verhindern.
  • Sicherheit: Warum PDO::prepare() und execute() SQL-Injections unmöglich machen.
  • Praxis: Empfangen der POST-Daten, Plausibilitätsprüfung (Text darf nicht leer sein), Speichern in SQLite und Redirect auf die Startseite.
  • Ergebnis: Ein Eintrag kann eingegeben werden und landet sicher in der Datenbank.

Kapitel 7: Einträge aus SQLite auflisten & XSS-Schutz

  • PHP-Theorie: Daten abfragen mit PDO::query() bzw. fetchAll(PDO::FETCH_ASSOC).
  • Sicherheit: Was ist XSS (Cross-Site Scripting)? Output-Escaping mit htmlspecialchars().
  • Praxis:
    • Auflistung der Einträge als Karten in einer foreach-Schleife.
    • Zeilenumbrüche im Fließtext erhalten (nl2br()).
    • Empty-State ("Noch keine Einträge vorhanden – schreib deinen ersten!").
  • Ergebnis: Die Startseite zeigt alle in SQLite gespeicherten Einträge sicher an.

Kapitel 8: Markdown-Power mit Parsedown (Single-File)

  • Fremden Code verstehen: Wie bindet man externe Bibliotheken ohne Tools ein (require_once __DIR__ . '/lib/Parsedown.php').
  • Markdown-Rendering: Einträge wie in DayOne mit Formatierungen (**fett**, *kursiv*, # Überschrift, - Liste) versehen.
  • Sicherheit mit Parsedown: Warum Parsedown eigenes Escaping mitbringt (setSafeMode(true)).
  • Ergebnis: Deine Einträge unterstützen volles Markdown – genau wie das echte DayOne.

Kapitel 9: Pagination (Blättern durch Seiten)

  • PHP-Theorie: Mathematische Logik (ceil, Typ-Casting (int)), Query-Parameter per $_GET['page'].
  • Datenbank: SQL-Befehle LIMIT und OFFSET, Zählen aller Zeilen mit COUNT(*).
  • Praxis:
    • Feste Anzahl von z. B. 5 Einträgen pro Seite.
    • Schicke Pagination-Controls ("Vorherige", "Nächste", Seitenzahlen).
  • Ergebnis: Auch bei vielen Einträgen bleibt das Journal performant und übersichtlich.

Kapitel 10: Eintrag bearbeiten & Löschen (Update & Delete)

  • PHP-Theorie: Umgang mit URL-Parametern (?action=edit&id=4), Bestätigungsdialoge, Löschen per POST (nicht per GET!).
  • Praxis:
    • Aktionsleiste an jeder Karte (Bearbeiten, Löschen).
    • Formular zur Bearbeitung mit bestehenden Werten vorbefüllen (UPDATE-Query).
    • Lösch-Handler mit Sicherheitsnachfrage.
  • Ergebnis: Volles CRUD-Set (Create, Read, Update, Delete) ist komplett und funktional.

Kapitel 11: Tags parsen, speichern & filtern

  • PHP-Theorie: String-Manipulation (explode, trim, array_filter), Array-Funktionen.
  • Praxis:
    • Normalisierung der eingegebenen Tags ("Reisen, Idee, reisen" -> ['reisen', 'idee']).
    • Tags als anklickbare Badges/Chips an jedem Eintrag darstellen.
    • Klick auf einen Tag filtert die Liste (?tag=reisen).
  • Ergebnis: Einträge können nach Themen gefiltert werden.

Phase 3: DayOne Features & Authentifizierung

Kapitel 12: "On This Day" (An diesem Tag in früheren Jahren)

  • PHP-Theorie: Datums-Filterung, SQL-Datumsfunktionen (strftime in SQLite).
  • Praxis:
    • Dedicated View: Zeige alle Einträge, deren Tag und Monat mit dem heutigen Tag übereinstimmen, aber aus Vorjahren stammen (2025, 2024, ...).
    • Gruppierung nach Jahren ("Vor 1 Jahr", "Vor 2 Jahren").
  • Ergebnis: Die klassische DayOne-Nostalgie-Funktion ist live.

Kapitel 13: Volltextsuche

  • PHP-Theorie: Dynamische Abfrage-Parameter, sichere Suche mit LIKE %...%.
  • Praxis:
    • Suchleiste im Header oder als eigene Suchseite.
    • Suche über Textinhalt und Tags.
    • Treffer-Hervorhebung (Highlighting) im Text via PHP str_ireplace oder preg_replace.
  • Ergebnis: Blitzschnelles Auffinden von Erinnerungen.

Kapitel 14: Journal-Statistiken (Stats Page)

  • PHP-Theorie: Komplexe SQL-Aggregationen (COUNT, GROUP BY, ORDER BY), Verarbeitungslogik in PHP.
  • Praxis:
    • Gesamtanzahl Einträge und Wörter.
    • Schreib-Serie (Streaks: Wie viele Tage in Folge geschrieben?).
    • Stimmungs-Verteilung (Mood-Barometer) mit einfacher CSS-Balkengrafik.
    • Häufigste Tags.
  • Ergebnis: Ein ansprechendes Dashboard mit Insights zum eigenen Schreibverhalten.

Kapitel 15: Single-User Login & Sessions (Auth)

  • PHP-Theorie: Wie Sessions funktionieren (session_start(), Cookies, $_SESSION).
  • Sicherheit: password_hash() und password_verify(), Session Hijacking Basics (session_regenerate_id).
  • Praxis:
    • Konfiguriertes Master-Passwort (in .env oder Config).
    • Login-Maske, Auth-Middleware (Schutz aller Seiten vor unbefugtem Zugriff), Logout-Button.
  • Ergebnis: Das Tagebuch ist privat und durch ein Passwort geschützt.

Phase 4: Medien, UX & Feinschliff

Kapitel 16: File-Uploads & Bildanhänge (Kleine Galerie)

  • PHP-Theorie: $_FILES, enctype="multipart/form-data", php.ini-Limits (upload_max_filesize).
  • Sicherheit: Mime-Type Validierung (finfo), Dateinamen hashen (keine Originaldateinamen auf der Festplatte ausführen), Speicherort absichern.
  • Praxis:
    • Bilder hochladen (1-3 Bilder pro Eintrag).
    • Bilder im Upload-Ordner speichern, Pfad in SQLite referenzieren.
    • Schicke responsive Mini-Galerie auf der Eintrags-Karte.
  • Ergebnis: Einträge können mit Fotos illustriert werden.

Kapitel 17: Quick Capture & Daily Log („Append to Today“)

  • PHP / UX / Business-Logik: Schnellerfassung für flüchtige Gedanken ohne Unterseiten-Wechsel:
    • Quick-Capture-Leiste: Schlankes Eingabefeld direkt oben auf index.php (mit Ctrl/Cmd + Enter Tastatur-Shortcut).
    • Das „Append-to-Today“-Muster:
      • Prüfen via SQL: Existiert für das heutige Datum (date('now')) bereits ein Eintrag?
      • Falls ja: Neuen Text automatisch mit aktuellem Zeitstempel (z. B. **14:30** — Notiz) an den bestehenden Tagebucheintrag anhängen (UPDATE ... SET text = text || ...).
      • Falls nein: Automatisch den ersten Eintrag für den heutigen Tag anlegen (INSERT).
    • Das Zusammenspiel: Schnelle Tages-Notizen direkt im Stream, ausführliche Long-Form-Einträge weiterhin im großen Editor (new.php / edit.php).
  • Ergebnis: Höchster Schreibkomfort wie in modernen Apps (Logseq, DayOne Daily Notes) – kein Barriere-Moment beim Festhalten spontaner Momente.

Kapitel 18: Code-Struktur & Refactoring (DRY & Helper)

  • PHP-Theorie: DRY-Prinzip (Don't Repeat Yourself), Erstellen von Helper-Funktionen (helpers.php für Datumsformatierung, Tag-Rendering, Flash-Messages).
  • Praxis: Bereinigen von Duplikaten, Auslagerung wiederkehrender UI-Fragmente in wiederverwendbare Komponenten.
  • Ergebnis: Aufgeräumter, lesbarer und wartbarer Code.

Kapitel 19: Modernes PHP: Composer, Autoloading & Kurs-Rückblick

  • Der Aha-Moment: Was löst Composer? Warum manuelles Herunterladen von Bibliotheken auf Dauer nervt.
  • Praxis:
    • Composer im Docker-Container nutzen (composer init).
    • Parsedown via Composer installieren (composer require erusev/parsedown).
    • Den PSR-4 Autoloader verstehen (require_once 'vendor/autoload.php').
    • Refactoring: Die alte lib/Parsedown.php löschen und sehen, wie Composer alles sauber verwaltet.
  • Rückblick & Ausblick:
    • Was haben wir gelernt? (HTTP, PDO/SQLite, Sessions, Security, CSS ohne Framework, File Uploads, Composer).
    • Wie geht es weiter? (Router, Microframeworks wie Slim, Export-Funktionen).
  • Ergebnis: Vollständig funktionierendes, modernes, sicheres Tagebuch mit professionellem Dependency-Management!

🔮 Ausblick & Zukunfts-Ideen (Post-Course / Phase 5)

Ideenspeicher für spannende Erweiterungen nach Abschluss des 18-Kapitel-Kurses:

📱 Progressive Web App (PWA) & Offline-Sync

  • Homescreen-Installation: manifest.json für App-Icon, Standalone-Modus (keine Browser-Adressleiste) und Theme-Farben.
  • Offline-Caching: Service Worker (sw.js) zum Cachen von CSS, Icons und App-Skelett für blitzschnelles Laden auch ohne Netz.
  • Offline-First Eintragserfassung:
    • Wenn kein Internet vorhanden ist: Neuen Eintrag lokal im Browser ablegen (localStorage oder IndexedDB).
    • Sobald wieder online (navigator.onLine / window.ononline Event): Automatisch im Hintergrund per POST-Request an PHP übertragen.
  • PHP Sync-Endpunkt: Schlanker JSON-API-Endpunkt in PHP (api/sync.php), der php://input empfängt und per Prepared Statements in die SQLite-Datenbank schreibt.

🔒 Komfort & Datenhoheit

  • Zwei-Faktor-Authentifizierung (2FA): Optionaler TOTP-Generator (z. B. via Google Authenticator).
  • Backup & Export: Automatischer Export der SQLite-Datenbank und aller Bilder als .zip oder Markdown-Archiv per Knopfdruck.
  • Themes: Umschalter zwischen Hell-, Dunkel- und Sepia-Modus.

🚀 Wie wir vorgehen

  1. Jeder Kapitel-Ordner ist 100% autark und lauffähig: Man kann in jeden Ordner (cd kapitel-01, cd kapitel-02 usw.) wechseln und ihn sofort per docker compose up -d im Browser testen.
  2. Evolution statt Zauberei: Jedes Kapitel baut auf dem vorherigen auf. Neue Konzepte werden erst verständlich erprobt und im nächsten Schritt sauber refaktoriert.
  3. Schritt für Schritt: Wir gehen Kapitel für Kapitel gemeinsam durch. Du liest, probierst aus und bestimmst das Tempo.