Umsetzung – Struktur, Routing und Datenbank‑Abbildung
Erste Schritte: Umsetzung – Struktur, Routing und Datenbank‑Abbildung
In diesem Tutorial setzen wir die zuvor geplante TaskBoard‑Mini‑App praktisch um.
Fokus: Verzeichnisstruktur, Front‑Controller + Routing und die Abbildung des Datenmodells
(Task‑Tabelle) auf eine einfache Model‑Klasse.
1. Verzeichnisstruktur anlegen
/taskboard ├── composer.json ├── public/ # öffentlich erreichbar (Document‑Root) │ ├── index.php # Front‑Controller │ └── assets/ # CSS, JS, Bilder ├── src/ # Application Code (PSR‑4) │ ├── Controller/ │ │ └── TaskController.php │ ├── Model/ │ │ └── Task.php │ └── Core/ │ ├── Router.php │ └── Database.php └── views/ ├── tasks/ │ ├── list.php │ └── form.php └── layout.php
composer.json (Ausschnitt)
{ "autoload": { "psr-4": { "App\\": "src/" } }, "require": { "vlucas/valitron": "^1.4" # Beispiel‑Validator } }
Nach dem Anlegen:
composer install
und
composer dump-autoload
.
2. Core\Database – PDO‑Wrapper
PDO::ERRMODE_EXCEPTION ]); } return self::$pdo; } } ?>
3. Model\Task – Datenbank‑Abbildung (Active‑Record‑Light)
query("SELECT * FROM tasks ORDER BY id DESC"); return $stmt->fetchAll(PDO::FETCH_CLASS, self::class); } public static function find(int $id): ?self { $stmt = Database::conn()->prepare("SELECT * FROM tasks WHERE id = :id"); $stmt->execute([':id' => $id]); return $stmt->fetchObject(self::class) ?: null; } public function save(): void { $pdo = Database::conn(); if (isset($this->id)) { $sql = "UPDATE tasks SET title=:t, description=:d, status=:s WHERE id=:id"; $pdo->prepare($sql)->execute([ ':t'=>$this->title, ':d'=>$this->description, ':s'=>$this->status, ':id'=>$this->id ]); } else { $sql = "INSERT INTO tasks (title,description,status) VALUES (:t,:d,:s)"; $pdo->prepare($sql)->execute([ ':t'=>$this->title, ':d'=>$this->description, ':s'=>$this->status ]); $this->id = (int)$pdo->lastInsertId(); } } public static function delete(int $id): void { Database::conn()->prepare("DELETE FROM tasks WHERE id=:id")->execute([':id'=>$id]); } } ?>
4. Core\Router – simples Mapping
routes[] = [$method, "#^$pattern$#", $handler]; } public function dispatch(string $method, string $uri): void { foreach ($this->routes as [$m,$regex,$h]) { if ($m === $method && preg_match($regex, $uri, $matches)) { array_shift($matches); return is_array($h) ? (new $h[0])->{$h[1]}(...$matches) : $h(...$matches); } } http_response_code(404); echo "404 – Not Found"; } } ?>
5. public/index.php – Front‑Controller
add('GET', '/', [TaskController::class, 'index']); $router->add('GET', '/task/new', [TaskController::class, 'create']); $router->add('POST', '/task/store', [TaskController::class, 'store']); $router->add('GET', '/task/(\d+)/edit', [TaskController::class, 'edit']); $router->add('POST', '/task/(\d+)/update',[TaskController::class, 'update']); $router->add('POST', '/task/(\d+)/del', [TaskController::class, 'destroy']); $router->dispatch($_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); ?>
6. Controller\TaskController – Geschäftslogik
save(); } public function update(int $id) { $this->save($id); } private function save(?int $id=null): void { $task = $id ? Task::find($id) : new Task(); $task->title = trim($_POST['title'] ?? ''); $task->description = trim($_POST['desc'] ?? ''); $task->status = $_POST['status'] ?? 'open'; $task->save(); header('Location: /'); exit; } public function destroy(int $id) { Task::delete($id); header('Location: /'); } } ?>
7. View – Aufgabenliste (views/tasks/list.php)
layout.php liefert simple Wrapper‑Funktionen
start()
/
end()
zum Einfügen in den HTML‑Rahmen – Details ausgelassen.
8. Migration ausführen
mysql -u user -p taskboard < create_tasks.sql # siehe vorheriges Tutorial
Fazit
Mit dieser Grundstruktur – Core‑Router, Active‑Record‑ähnlichem Model und Views –
steht das Fundament deiner TaskBoard‑App.
Von hier aus kannst du Features wie CSRF‑Token, Login, AJAX‑Drag‑and‑Drop oder Tests
schrittweise ergänzen, ohne das Gerüst zu verändern.