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.