Diese Woche am beliebtesten

Vertiefendes Material

das Short Book

Willkommen beim Dreamcodes Short Gästebuch. Hier kannst du persönliche Nachrichten, Grüße oder Feedback hinterlassen, die für andere Besucher sichtbar sind. Jede Nachricht wird mit dem Namen des Verfassers und dem Datum der Eintragung angezeigt, sodass ein Überblick über alle Einträge leicht möglich ist.

Funktionsweise

Wenn du eine Nachricht einträgst, wird sie sicher in der Datenbank gespeichert und sofort im Gästebuch angezeigt. Jede Eintragung enthält den Namen, die Nachricht selbst und den Zeitpunkt der Erstellung. Um Spam und automatisierte Einträge zu vermeiden, gibt es eine einfache Captcha-Abfrage, die vor dem Absenden gelöst werden muss.

Verwaltung und Sicherheit

Ein Administrator hat die Möglichkeit, Einträge jederzeit zu löschen, insbesondere um Spam oder unerwünschte Inhalte zu entfernen. Alle Einträge werden sicher gespeichert und sind nur über diese Gästebuchseite einsehbar. Gelöschte Einträge können nicht wiederhergestellt werden.

Vorteile

  • Einfaches Hinzufügen von Einträgen: Name und Nachricht eingeben, Captcha lösen, absenden
  • Sichtbare Historie: Alle bisherigen Nachrichten werden in chronologischer Reihenfolge angezeigt
  • Admin-Kontrolle: Unerwünschte Einträge können sofort gelöscht werden
  • Spam-Schutz: Ein simples Captcha verhindert automatisierte Einträge
<?php
define('DB_FILE', __DIR__ . '/guestbook.sqlite');

// Initialize DB
$db = new SQLite3(DB_FILE);
$db->exec("CREATE TABLE IF NOT EXISTS entries (
    id INTEGER PRIMARY KEY,
    name TEXT,
    message TEXT,
    created_at INTEGER
)");

function escape($str){ return htmlspecialchars($str, ENT_QUOTES,'UTF-8'); }

function jsonResponse($data,$code=200){
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data);
    exit;
}

// Handle new entry
if($_SERVER['REQUEST_METHOD']==='POST' && isset($_GET['action']) && $_GET['action']==='add'){
    $name = trim($_POST['name'] ?? '');
    $message = trim($_POST['message'] ?? '');
    if(!$name || !$message) jsonResponse(['error'=>'Name und Nachricht erforderlich'],400);

    // Optional: simple captcha
    if(isset($_POST['captcha'])){
        if(trim($_POST['captcha']) !== '5') jsonResponse(['error'=>'Captcha falsch'],400);
    }

    $stmt = $db->prepare('INSERT INTO entries (name,message,created_at) VALUES (:name,:message,:created_at)');
    $stmt->bindValue(':name',$name,SQLITE3_TEXT);
    $stmt->bindValue(':message',$message,SQLITE3_TEXT);
    $stmt->bindValue(':created_at',time(),SQLITE3_INTEGER);
    $stmt->execute();
    jsonResponse(['success'=>true]);
}

// Admin delete
if($_SERVER['REQUEST_METHOD']==='POST' && isset($_GET['action']) && $_GET['action']==='delete'){
    $id = intval($_POST['id'] ?? 0);
    if($id<=0) jsonResponse(['error'=>'Ungültige ID'],400);
    $stmt = $db->prepare('DELETE FROM entries WHERE id=:id');
    $stmt->bindValue(':id',$id,SQLITE3_INTEGER);
    $stmt->execute();
    jsonResponse(['success'=>true]);
}

// Fetch entries
if(isset($_GET['action']) && $_GET['action']==='list'){
    $res = $db->query('SELECT * FROM entries ORDER BY created_at DESC');
    $entries=[];
    while($row=$res->fetchArray(SQLITE3_ASSOC)){
        $entries[]=[
            'id'=>$row['id'],
            'name'=>escape($row['name']),
            'message'=>escape($row['message']),
            'created_at'=>date('d.m.Y H:i',$row['created_at'])
        ];
    }
    jsonResponse($entries);
}

// Serve UI
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Dreamcodes Short Gästebuch</title>
<style>
:root{--bg:#0f1724;--card:#0b1220;--accent:#7c3aed;--muted:#9aa4b2;--glass: rgba(255,255,255,0.03);}
body{font-family:Inter, sans-serif;background:linear-gradient(180deg,var(--bg),#071028);color:#e6eef8;margin:0;padding:40px;}
.container{max-width:800px;margin:0 auto}
.card{background:linear-gradient(180deg,var(--card),#071022);padding:28px;border-radius:16px;box-shadow:0 10px 30px rgba(2,6,23,0.7);margin-bottom:24px}
h1{font-size:24px;margin:0 0 8px}
p.lead{color:var(--muted);margin:0 0 20px}
.inputtext{background:transparent;border:1px solid rgba(255,255,255,0.04);padding:8px 10px;border-radius:8px;color:inherit;width:100%;margin-bottom:10px}
.btn{background:var(--accent);color:white;padding:10px 14px;border-radius:10px;border:none;cursor:pointer;font-weight:600}
.entry{padding:12px;margin-bottom:12px;background:rgba(255,255,255,0.02);border-radius:10px}
.entry-meta{font-size:13px;color:var(--muted)}
.deleteBtn{background:#ff4c4c;padding:4px 8px;font-size:12px;border-radius:6px;margin-left:10px;cursor:pointer}
footer{margin-top:18px;text-align:center;color:var(--muted);font-size:13px}
.thin{opacity:0.8}
</style>
</head>
<body>
<div class="container">
<div class="card">
<h1>Gästebuch</h1>
<p class="lead">Hinterlasse eine Nachricht oder Grüße für andere Besucher</p>
<input id="name" class="inputtext" type="text" placeholder="Dein Name">
<textarea id="message" class="inputtext" placeholder="Deine Nachricht"></textarea>
<label class="small">Captcha: Was ist 2 + 3? (Anti-Spam)</label>
<input id="captcha" class="inputtext" type="text" placeholder="Antwort">
<button id="submitBtn" class="btn">Absenden</button>
<div id="error" style="color:#ffb4b4;margin-top:10px"></div>
</div>
<div id="entries"></div>
<footer><div class="thin">Powered by Dreamcodes.NET</div></footer>
</div>
<script>
async function fetchEntries(){
    const resp = await fetch('?action=list');
    const data = await resp.json();
    const container = document.getElementById('entries');
    container.innerHTML='';
    data.forEach(e=>{
        const div=document.createElement('div');
        div.className='card entry';
        div.innerHTML=`<strong>${e.name}</strong><div class='entry-meta'>${e.created_at}</div><p>${e.message}</p><button onclick='deleteEntry(${e.id})' class='deleteBtn'>Löschen</button>`;
        container.appendChild(div);
    });
}

async function deleteEntry(id){
    if(!confirm('Eintrag wirklich löschen?')) return;
    const fd=new FormData(); fd.append('id',id);
    const resp=await fetch('?action=delete',{method:'POST',body:fd});
    const data=await resp.json();
    if(data.success) fetchEntries();
}

document.getElementById('submitBtn').addEventListener('click',async()=>{
    const fd=new FormData();
    fd.append('name',document.getElementById('name').value);
    fd.append('message',document.getElementById('message').value);
    fd.append('captcha',document.getElementById('captcha').value);
    const resp=await fetch('?action=add',{method:'POST',body:fd});
    const data=await resp.json();
    if(data.success){
        document.getElementById('name').value='';
        document.getElementById('message').value='';
        document.getElementById('captcha').value='';
        fetchEntries();
        document.getElementById('error').textContent='';
    }else{ document.getElementById('error').textContent=data.error||'Fehler' }
});

fetchEntries();
</script>
</body>
</html>
Dreamcodes Redaktion
Dreamcodes Redaktion
Jeder Inhalt auf Dreamcodes entsteht mit einem klaren Anspruch: geprüfte Praxis statt schneller Theorie. Was hier veröffentlicht wird, basiert auf Best Practices, echten Projekterfahrungen und technischem Verständnis, das über das Offensichtliche hinausgeht. Unser Ziel ist ein Fundament, auf dem du aufbauen kannst, nicht eines, das beim ersten produktiven Einsatz bricht. Wie du die Inhalte integrierst, absicherst und in deinen Kontext überträgst, liegt bei dir. Die fachliche Grundlage liefern wir, die Verantwortung für den Einsatz bleibt deine.
Vorheriges Tutorial
Nächstes Tutorial

Vielleicht einen Blick WERT?