Kapitel 8
productdetail.php – Detailseite
Wird per ?id=xxx aufgerufen. Zeigt Details eines Produkts und hat das Formular "In den Warenkorb". Wenn die ID nicht existiert oder das Produkt gesperrt ist: Redirect zur Startseite.
Der Code
productdetail.php
<?php
require_once('db.php');
session_start();
// id aus url holen und in int casten (sicherheit)
$id = (int)($_GET['id'] ?? 0);
// produkt aus db holen (prepared statement wegen user-input aus url!)
$stmt = $conn->prepare("SELECT id, name, price, description, picture, artikelcode
FROM products
WHERE id = ? AND freigeben = 1");
$stmt->execute([$id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
// wenn kein produkt gefunden → zurück zur startseite
if (!$product) {
header('Location: index.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title><?= htmlspecialchars($product['name'], ENT_QUOTES, 'UTF-8') ?> - Webshop</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<?php include('navbar.php'); ?>
<div>
<h1><?= htmlspecialchars($product['name'], ENT_QUOTES, 'UTF-8') ?></h1>
<img src="<?= htmlspecialchars($product['picture'], ENT_QUOTES, 'UTF-8') ?>"
alt="<?= htmlspecialchars($product['name'], ENT_QUOTES, 'UTF-8') ?>"
style="max-width: 300px;">
<p><strong>Artikelnummer:</strong> <?= htmlspecialchars($product['artikelcode'], ENT_QUOTES, 'UTF-8') ?></p>
<p><strong>Preis:</strong> <?= htmlspecialchars($product['price'], ENT_QUOTES, 'UTF-8') ?> €</p>
<p><strong>Beschreibung:</strong><br>
<?= htmlspecialchars($product['description'], ENT_QUOTES, 'UTF-8') ?>
</p>
<form action="cart_add.php" method="POST">
<input type="hidden" name="produkt_id" value="<?= (int)$product['id'] ?>">
<label>Menge:
<input type="number" name="menge" value="1" min="1" max="99">
</label>
<button type="submit">In den Warenkorb</button>
</form>
</div>
<a href="index.php">← Zurück zur Übersicht</a>
</body>
</html>
Wichtige Details
- (int)($_GET['id'] ?? 0) – der Klassiker: wenn Parameter fehlt → 0, dann findet die Query nichts, dann Redirect. Wenn jemand
?id=abcschickt → wird zu 0. Wenn jemand?id=5; DROP TABLE usersschickt → wird zu 5, der Rest ist weg. - WHERE id = ? AND freigeben = 1 – gesperrte Produkte lassen sich auch nicht per direkter URL aufrufen. Konsistenz zu index.php.
- Redirect bei !$product – kein 404, keine leere Seite. User landet auf der Übersicht.
- hidden input mit (int) – der Wert im HTML wird sowieso vom Server generiert, aber Cast ist Absicherung falls jemand das HTML manipuliert bevor er's absendet.