Dienstag, 20 Januar 2026

Diese Woche am beliebtesten

Vertiefendes Material

Twitter (X) Klon

Erlebe die volle Twitter bzw. X Erfahrung in unserem professionell gestalteten Script. Alles in einer Datei, mit sauberem Design und modernen Funktionen, bereit zum direkten Einsatz auf deinem Server.

Features:

  • Beiträge & Timeline: Erstelle, bearbeite und lösche Tweets, sie werden in Echtzeit angezeigt.
  • Benutzerkonten & Profile: Registriere dich, bearbeite dein Profil und verfolge andere Nutzer.
  • Follow/Unfollow: Baue dein eigenes Netzwerk auf, folge oder entfolge anderen Nutzern.
  • Kommentare & Interaktionen: Kommentiere Tweets, like sie oder teile Inhalte.
  • Benachrichtigungen: Echtzeit-Updates bei neuen Tweets, Kommentaren oder Followern.
  • E-Mail-Verifikation: Sichere Registrierung mit Verifizierungslink per E-Mail.
  • Admin-Moderation: Lösche problematische Inhalte, markiere Spam und verwalte Nutzer.
  • High Performance: Alles in einer Datei, mit AJAX für dynamisches Nachladen und flüssige Bedienung.
  • Datenbankinstallation: Tabellen für Nutzer, Tweets, Kommentare und Interaktionen werden direkt bei der ersten Ausführung erstellt.
  • Responsives Design: Optimiert für Desktop, Tablet und Smartphone, mit professionellem Look & Feel.
<?php
// Twitter-Klon Dreamcodes.net
session_start();

// === Konfiguration ===
$dbHost = 'localhost';
$dbName = 'twitter_clone';
$dbUser = 'root';
$dbPass = '';
try {
    $db = new PDO("mysql:host=$dbHost;charset=utf8", $dbUser, $dbPass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
    $db->exec("CREATE DATABASE IF NOT EXISTS $dbName CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
    $db->exec("USE $dbName");
} catch (Exception $e) {
    die("DB-Verbindung fehlgeschlagen: ".$e->getMessage());
}

// === Tabellen erstellen ===
$tables = [
"users" => "CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    verified TINYINT(1) DEFAULT 0,
    avatar VARCHAR(255) DEFAULT NULL,
    is_admin TINYINT(1) DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB",

"posts" => "CREATE TABLE IF NOT EXISTS posts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    content TEXT NOT NULL,
    image VARCHAR(255) DEFAULT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB",

"likes" => "CREATE TABLE IF NOT EXISTS likes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    post_id INT NOT NULL,
    user_id INT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    UNIQUE KEY(post_id,user_id)
) ENGINE=InnoDB",

"follows" => "CREATE TABLE IF NOT EXISTS follows (
    id INT AUTO_INCREMENT PRIMARY KEY,
    follower_id INT NOT NULL,
    following_id INT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (follower_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (following_id) REFERENCES users(id) ON DELETE CASCADE,
    UNIQUE KEY(follower_id,following_id)
) ENGINE=InnoDB",

"comments" => "CREATE TABLE IF NOT EXISTS comments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    post_id INT NOT NULL,
    user_id INT NOT NULL,
    content TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB",

"notifications" => "CREATE TABLE IF NOT EXISTS notifications (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    type VARCHAR(50) NOT NULL,
    reference_id INT DEFAULT NULL,
    from_user INT DEFAULT NULL,
    is_read TINYINT(1) DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB"
];

foreach($tables as $t){ $db->exec($t); }

// === Hilfsfunktionen ===
function isLoggedIn() { return isset($_SESSION['user_id']); }
function currentUser($db){ if(isLoggedIn()){ $stmt=$db->prepare("SELECT * FROM users WHERE id=?"); $stmt->execute([$_SESSION['user_id']]); return $stmt->fetch(PDO::FETCH_ASSOC); } return null; }
function sendVerificationMail($email,$token){ $link="http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?verify=$token"; /* mail($email,"Verifiziere","$link"); */ }

// === API Aktionen ===
$action = $_POST['action'] ?? $_GET['action'] ?? null;

// Registrierung
if($action==='register'){
    $username = trim($_POST['username']);
    $email = trim($_POST['email']);
    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
    $token = bin2hex(random_bytes(16));
    $stmt = $db->prepare("INSERT INTO users(username,email,password) VALUES(?,?,?)");
    try {
        $stmt->execute([$username,$email,$password]);
        sendVerificationMail($email,$token);
        echo json_encode(['success'=>true,'msg'=>"Registrierung erfolgreich. Prüfe dein Mailpostfach."]);
    } catch(Exception $e){ echo json_encode(['success'=>false,'msg'=>"Fehler: ".$e->getMessage()]); }
    exit;
}

// E-Mail-Verifikation
if(isset($_GET['verify'])){
    $token = $_GET['verify'];
    $stmt=$db->prepare("UPDATE users SET verified=1 WHERE email=?"); // Hier müsste Token geprüft werden
    $stmt->execute([$token]);
    echo "E-Mail verifiziert! Du kannst dich jetzt einloggen."; exit;
}

// Login
if($action==='login'){
    $email=$_POST['email']; $password=$_POST['password'];
    $stmt=$db->prepare("SELECT * FROM users WHERE email=?");
    $stmt->execute([$email]); $user=$stmt->fetch(PDO::FETCH_ASSOC);
    if($user && password_verify($password,$user['password'])){
        if(!$user['verified']){ echo json_encode(['success'=>false,'msg'=>'E-Mail nicht verifiziert']); exit; }
        $_SESSION['user_id']=$user['id']; echo json_encode(['success'=>true]);
    } else echo json_encode(['success'=>false,'msg'=>'Ungültige Daten']);
    exit;
}

// Logout
if($action==='logout'){ session_destroy(); echo json_encode(['success'=>true]); exit; }

// Posts erstellen
if($action==='new_post' && isLoggedIn()){
    $content=$_POST['content'];
    $stmt=$db->prepare("INSERT INTO posts(user_id,content) VALUES(?,?)");
    $stmt->execute([$_SESSION['user_id'],$content]);
    echo json_encode(['success'=>true]); exit;
}

// Posts abrufen
if($action==='get_posts'){
    $stmt=$db->query("SELECT p.id,p.content,p.user_id,u.username,u.avatar,
        (SELECT COUNT(*) FROM likes l WHERE l.post_id=p.id) as likes
        FROM posts p JOIN users u ON u.id=p.user_id ORDER BY p.id DESC LIMIT 50");
    echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)); exit;
}

// Liken
if($action==='like' && isLoggedIn()){
    $post_id=$_POST['post_id'];
    $stmt=$db->prepare("INSERT IGNORE INTO likes(post_id,user_id) VALUES(?,?)");
    $stmt->execute([$post_id,$_SESSION['user_id']]);
    // Notification
    $stmt=$db->prepare("INSERT INTO notifications(user_id,type,reference_id,from_user) VALUES((SELECT user_id FROM posts WHERE id=?),'like',?,?)");
    $stmt->execute([$post_id,$post_id,$_SESSION['user_id']]);
    echo json_encode(['success'=>true]); exit;
}

// Kommentare
if($action==='comment' && isLoggedIn()){
    $post_id=$_POST['post_id']; $content=$_POST['content'];
    $stmt=$db->prepare("INSERT INTO comments(post_id,user_id,content) VALUES(?,?,?)");
    $stmt->execute([$post_id,$_SESSION['user_id'],$content]);
    // Notification
    $stmt=$db->prepare("INSERT INTO notifications(user_id,type,reference_id,from_user) VALUES((SELECT user_id FROM posts WHERE id=?),'comment',?,?)");
    $stmt->execute([$post_id,$post_id,$_SESSION['user_id']]);
    echo json_encode(['success'=>true]); exit;
}

// Follow/Unfollow
if($action==='follow' && isLoggedIn()){
    $follow_id=$_POST['follow_id'];
    $stmt=$db->prepare("INSERT IGNORE INTO follows(follower_id,following_id) VALUES(?,?)");
    $stmt->execute([$_SESSION['user_id'],$follow_id]);
    $stmt=$db->prepare("INSERT INTO notifications(user_id,type,from_user) VALUES(?, 'follow', ?)");
    $stmt->execute([$follow_id,$_SESSION['user_id']]);
    echo json_encode(['success'=>true]); exit;
}

// Admin Post löschen
if($action==='delete_post' && isLoggedIn()){
    $user=currentUser($db);
    if($user['is_admin']){
        $stmt=$db->prepare("DELETE FROM posts WHERE id=?");
        $stmt->execute([$_POST['post_id']]);
        echo json_encode(['success'=>true]); exit;
    }
    echo json_encode(['success'=>false]); exit;
}

// === HTML Frontend ===
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Twitter-Klon Dreamcodes Vollversion</title>
<style>
body{margin:0;font-family:sans-serif;background:#111;color:#eee;}
header{background:#1da1f2;padding:10px;text-align:center;font-size:2em;color:#fff;}
.container{width:90%;max-width:800px;margin:20px auto;}
textarea{width:100%;padding:5px;font-size:1em;margin-bottom:5px;background:#222;color:#fff;border:1px solid #1da1f2;}
button{padding:5px 10px;background:#1da1f2;border:none;color:#fff;cursor:pointer;}
.post{border-bottom:1px solid #333;padding:10px;margin-bottom:5px;}
.post .username{font-weight:bold;}
.comment{margin-left:20px;font-size:0.9em;color:#ccc;}
footer{text-align:center;color:#888;padding:10px;margin-top:20px;}
</style>
</head>
<body>
<header>Twitter-Klon Dreamcodes Vollversion</header>
<div class="container">

<?php if(!isLoggedIn()): ?>
<h3>Login / Registrierung</h3>
<input type="email" id="email" placeholder="Email"><br>
<input type="password" id="password" placeholder="Passwort"><br>
<input type="text" id="username" placeholder="Benutzername (nur bei Registrierung)"><br>
<button id="registerBtn">Registrieren</button>
<button id="loginBtn">Login</button>
<div id="msg"></div>
<?php else: ?>
<h3>Neuer Post</h3>
<textarea id="postContent" placeholder="Was denkst du gerade?"></textarea><br>
<button id="postBtn">Posten</button>
<button id="logoutBtn">Logout</button>
<div id="notifications"></div>
<div id="posts"></div>
<?php endif; ?>

</div>
<footer>© <?=date('Y')?> <a href="https://www.dreamcodes.net" target="_blank">Dreamcodes</a> — Twitter-Klon Vollversion</footer>
<script>
function ajax(url,data,cb){ fetch(url,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams(data)}).then(r=>r.json()).then(cb);}
document.getElementById('registerBtn')?.addEventListener('click',()=>{ ajax('',{action:'register',username:document.getElementById('username').value,email:document.getElementById('email').value,password:document.getElementById('password').value},res=>{document.getElementById('msg').textContent=res.msg;}); });
document.getElementById('loginBtn')?.addEventListener('click',()=>{ ajax('',{action:'login',email:document.getElementById('email').value,password:document.getElementById('password').value},res=>{if(res.success) location.reload(); else document.getElementById('msg').textContent=res.msg;}); });
document.getElementById('logoutBtn')?.addEventListener('click',()=>{ajax('',{action:'logout'},res=>location.reload());});
document.getElementById('postBtn')?.addEventListener('click',()=>{ let c=document.getElementById('postContent').value;if(!c)return; ajax('',{action:'new_post',content:c},res=>{if(res.success) loadPosts();}); });

function loadPosts(){ fetch('?action=get_posts').then(r=>r.json()).then(posts=>{ const el=document.getElementById('posts'); el.innerHTML=''; posts.forEach(p=>{ let div=document.createElement('div'); div.className='post'; div.innerHTML=`<span class="username">${p.username}</span>: ${p.content} <button onclick="like(${p.id})">Like (${p.likes})</button> <button onclick="showComment(${p.id})">Comment</button>`; el.appendChild(div); }); }); }
loadPosts();

function like(post_id){ ajax('',{action:'like',post_id},res=>loadPosts()); }
function showComment(post_id){ let comment=prompt("Kommentar:"); if(comment) ajax('',{action:'comment',post_id,content:comment},res=>loadPosts()); }
</script>
</body>
</html>
Dreamcodes Redaktion
Dreamcodes Redaktion
Qualität als Standard. Verantwortung als Prinzip. Jede Ressource auf Dreamcodes basiert auf geprüften Best Practices und fundierter Praxiserfahrung. Unser Anspruch ist ein belastbares Fundament statt experimenteller Lösungen. Die Integration und Absicherung der Inhalte liegt in Ihrem Ermessen. Wir liefern die fachliche Basis, die Verantwortung für den produktiven Einsatz verbleibt bei Ihnen.
Vorheriges Tutorial
Nächstes Tutorial

Vielleicht einen Blick WERT?