The user wants to convert the provided HTML/CSS/JavaScript chat room demo into a real working application using HTML, CSS, PHP, and a database (implied by "real" and "host"). Key requirements: 1. Convert the frontend demo to a real backend application 2. Use PHP for backend 3. Use MySQL/MariaDB for database (implied by "real") 4. Keep the Persian (Farsi) language and RTL layout 5. Maintain the modern UI design from the original code 6. Make it functional (real login/register, real chat messages stored in DB) 7. Should be deployable on a web host Since I need to provide a single HTML file as per system instructions, but the user is asking for PHP/MySQL backend, I need to provide: 1. The complete PHP code structure 2. SQL schema 3. Instructions on how to set it up 4. But since I can only provide one file, I should provide a comprehensive solution that includes all PHP files concatenated or clearly separated with comments, plus the SQL setup. Wait, the system says "ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE" but the user is asking for PHP. This is a conflict. However, looking at the instructions carefully: "Generate complete, working HTML code that can be run immediately." But PHP cannot run in a single HTML file in the browser. I need to interpret this as: provide the complete source code for the application, which happens to be PHP files. Since I must output a single file, I'll provide a comprehensive solution with clear file separators (like comments indicating different files) containing all the PHP, SQL, and frontend code needed. Actually, looking at the system prompt again: "Generate complete, working HTML code that can be run immediately." This suggests the user wants code that works immediately. But PHP requires a server. Given the constraints, I should: 1. Provide the complete PHP application code with multiple files indicated 2. Provide the SQL schema 3. Provide instructions 4. But keep it as one text block/file with clear separators Or, I could create a single-file PHP solution that handles everything (routing, database setup, frontend) in one index.php file. This would technically be a single file that can run on a PHP host. Yes, that's the best approach for this constraint. I'll create a single PHP file (index.php) that: - Sets up the database on first run - Handles all backend logic (auth, chat CRUD) - Serves the frontend HTML/CSS/JS - Uses AJAX/Fetch for real-time-like updates (polling) Features to implement: 1. User registration/login with PHP sessions 2. MySQL database for users, rooms, messages 3. Real chat functionality (messages stored in DB) 4. Multiple rooms support 5. Online status tracking 6. Responsive design (maintain the original beautiful UI) 7. Security: Prepared statements, password hashing, XSS protection Database schema: - users (id, username, phone, password, avatar, status, last_active) - rooms (id, name, type, created_by) - messages (id, room_id, user_id, message, created_at) - room_members (id, room_id, user_id, joined_at) Since it's one file, I'll use a "setup mode" - if tables don't exist, create them. For real-time feel without WebSockets (which require separate server), I'll use polling every 3 seconds. Structure of the single PHP file: 1. PHP Backend Logic (session start, db connection, request handlers) 2. Database setup (create tables if not exist) 3. API endpoints (handled via GET/POST parameters) 4. HTML/CSS/JS Frontend (the beautiful UI from original, adapted for real backend) Security considerations: - Use PDO with prepared statements - Password_hash() for passwords - htmlspecialchars() for output - CSRF tokens - Input validation Let's build this step by step: Database connection config (at top): - Define DB credentials (user will change these) - Try to connect, if fail show setup instructions Routing: - If $_GET['action'] exists, handle API call - Else show the app interface API Endpoints: - login - register - get_messages - send_message - get_rooms - create_room - logout Frontend: - Same beautiful Persian UI as original - But now AJAX calls to the same file with ?action=... - Poll for new messages - Show real user data from session I'll maintain the exact styling from the user's provided code but adapt the JavaScript to work with the PHP backend. Since it's one file, I need to be careful about output buffering and headers. Let me write the code: File: index.php (all-in-one) Sections: 1. PHP Logic (top) - Session start - DB config - Helper functions - Request routing 2. Database Setup - Create tables if not exist 3. API Handlers - JSON responses for AJAX 4. HTML Output (if not API call) - Same structure as original but with PHP session integration The UI should look almost identical to what the user provided, but functional. Key adaptations: - Login form submits to ?action=login via fetch - Register form submits to ?action=register - Messages load from ?action=get_messages - Send message to ?action=send_message - Auto-refresh messages every 2-3 seconds I'll include the "Built with anycoder" link as required. Let's code this comprehensive solution. Here is the complete **real chat application** in a single PHP file (`index.php`). This includes the database setup, backend API, and the beautiful Persian UI you provided. **Instructions:** 1. Save this as `index.php` 2. Update the database credentials at the top (host, dbname, user, pass) 3. Upload to your PHP host (PHP 7.4+ with MySQL/MariaDB) 4. Visit the page - it will auto-create the database tables on first run ```php setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } catch(PDOException $e) { die("Connection failed: " . $e->getMessage()); } // Initialize Database Tables (Auto-setup on first run) function initDB($pdo) { $pdo->exec("CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(100) NOT NULL, phone VARCHAR(20) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, avatar VARCHAR(10) DEFAULT '👤', status ENUM('online', 'offline') DEFAULT 'offline', last_active TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS rooms ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, type ENUM('public', 'private') DEFAULT 'public', created_by INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS messages ( id INT AUTO_INCREMENT PRIMARY KEY, room_id INT NOT NULL, user_id INT NOT NULL, message TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS room_members ( id INT AUTO_INCREMENT PRIMARY KEY, room_id INT NOT NULL, user_id INT NOT NULL, joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY unique_membership (room_id, user_id), FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci"); // Insert default public room if empty $stmt = $pdo->query("SELECT COUNT(*) FROM rooms"); if ($stmt->fetchColumn() == 0) { $pdo->prepare("INSERT INTO rooms (name, type) VALUES (?, ?)") ->execute(['عمومی', 'public']); $pdo->prepare("INSERT INTO rooms (name, type) VALUES (?, ?)") ->execute(['خصوصی', 'private']); } } // Initialize on first run initDB($pdo); // API Handler if (isset($_GET['action'])) { header('Content-Type: application/json; charset=utf-8'); $action = $_GET['action']; switch($action) { case 'register': handleRegister($pdo); break; case 'login': handleLogin($pdo); break; case 'logout': handleLogout(); break; case 'get_rooms': getRooms($pdo); break; case 'get_messages': getMessages($pdo); break; case 'send_message': sendMessage($pdo); break; case 'create_room': createRoom($pdo); break; case 'get_online_users': getOnlineUsers($pdo); break; } exit; } // Backend Functions function handleRegister($pdo) { $data = json_decode(file_get_contents('php://input'), true); $username = trim($data['username'] ?? ''); $phone = trim($data['phone'] ?? ''); $password = $data['password'] ?? ''; if (empty($username) || empty($phone) || empty($password)) { echo json_encode(['success' => false, 'error' => 'تمام فیلدها الزامی است']); return; } if (!preg_match('/^09[0-9]{9}$/', $phone)) { echo json_encode(['success' => false, 'error' => 'شماره موبایل نامعتبر است']); return; } $hash = password_hash($password, PASSWORD_BCRYPT); $avatar = mb_substr($username, 0, 1); try { $stmt = $pdo->prepare("INSERT INTO users (username, phone, password, avatar) VALUES (?, ?, ?, ?)"); $stmt->execute([$username, $phone, $hash, $avatar]); $userId = $pdo->lastInsertId(); // Auto-join public rooms $rooms = $pdo->query("SELECT id FROM rooms WHERE type = 'public'")->fetchAll(); $stmt = $pdo->prepare("INSERT INTO room_members (room_id, user_id) VALUES (?, ?)"); foreach ($rooms as $room) { $stmt->execute([$room['id'], $userId]); } $_SESSION['user_id'] = $userId; $_SESSION['username'] = $username; $_SESSION['avatar'] = $avatar; echo json_encode(['success' => true, 'user' => ['id' => $userId, 'username' => $username, 'avatar' => $avatar]]); } catch (PDOException $e) { if ($e->getCode() == 23000) { echo json_encode(['success' => false, 'error' => 'این شماره موبایل قبلاً ثبت شده است']); } else { echo json_encode(['success' => false, 'error' => 'خطا در ثبتنام']); } } } function handleLogin($pdo) { $data = json_decode(file_get_contents('php://input'), true); $phone = trim($data['phone'] ?? ''); $password = $data['password'] ?? ''; $stmt = $pdo->prepare("SELECT * FROM users WHERE phone = ?"); $stmt->execute([$phone]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['avatar'] = $user['avatar']; // Update status $pdo->prepare("UPDATE users SET status = 'online' WHERE id = ?")->execute([$user['id']]); echo json_encode(['success' => true, 'user' => ['id' => $user['id'], 'username' => $user['username'], 'avatar' => $user['avatar']]]); } else { echo json_encode(['success' => false, 'error' => 'شماره موبایل یا رمز عبور اشتباه است']); } } function handleLogout() { if (isset($_SESSION['user_id'])) { global $pdo; $pdo->prepare("UPDATE users SET status = 'offline' WHERE id = ?")->execute([$_SESSION['user_id']]); } session_destroy(); echo json_encode(['success' => true]); } function getRooms($pdo) { if (!isset($_SESSION['user_id'])) { echo json_encode(['success' => false]); return; } $stmt = $pdo->prepare(" SELECT r.*, (SELECT COUNT(*) FROM room_members WHERE room_id = r.id) as member_count, (SELECT COUNT(*) FROM users u JOIN room_members rm ON u.id = rm.user_id WHERE rm.room_id = r.id AND u.status = 'online') as online_count FROM rooms r JOIN room_members rm ON r.id = rm.room_id WHERE rm.user_id = ? ORDER BY r.id ASC "); $stmt->execute([$_SESSION['user_id']]); $rooms = $stmt->fetchAll(); echo json_encode(['success' => true, 'rooms' => $rooms]); } function getMessages($pdo) { if (!isset($_SESSION['user_id'])) { echo json_encode(['success' => false]); return; } $roomId = intval($_GET['room_id'] ?? 0); $lastId = intval($_GET['last_id'] ?? 0); // Verify membership $check = $pdo->prepare("SELECT id FROM room_members WHERE room_id = ? AND user_id = ?"); $check->execute([$roomId, $_SESSION['user_id']]); if (!$check->fetch()) { echo json_encode(['success' => false, 'error' => 'Access denied']); return; } $stmt = $pdo->prepare(" SELECT m.*, u.username, u.avatar FROM messages m JOIN users u ON m.user_id = u.id WHERE m.room_id = ? AND m.id > ? ORDER BY m.id ASC LIMIT 50 "); $stmt->execute([$roomId, $lastId]); $messages = $stmt->fetchAll(); // Update last active $pdo->prepare("UPDATE users SET last_active = NOW() WHERE id = ?")->execute([$_SESSION['user_id']]); echo json_encode(['success' => true, 'messages' => $messages]); } function sendMessage($pdo) { if (!isset($_SESSION['user_id'])) { echo json_encode(['success' => false]); return; } $data = json_decode(file_get_contents('php://input'), true); $roomId = intval($data['room_id'] ?? 0); $message = trim($data['message'] ?? ''); if (empty($message)) { echo json_encode(['success' => false]); return; } // Verify membership $check = $pdo->prepare("SELECT id FROM room_members WHERE room_id = ? AND user_id = ?"); $check->execute([$roomId, $_SESSION['user_id']]); if (!$check->fetch()) { echo json_encode(['success' => false, 'error' => 'Access denied']); return; } $stmt = $pdo->prepare("INSERT INTO messages (room_id, user_id, message) VALUES (?, ?, ?)"); $stmt->execute([$roomId, $_SESSION['user_id'], $message]); echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); } function createRoom($pdo) { if (!isset($_SESSION['user_id'])) { echo json_encode(['success' => false]); return; } $data = json_decode(file_get_contents('php://input'), true); $name = trim($data['name'] ?? ''); $type = $data['type'] ?? 'public'; if (empty($name)) { echo json_encode(['success' => false, 'error' => 'نام اتاق الزامی است']); return; } // Check room limit (max 3 per user) $stmt = $pdo->prepare("SELECT COUNT(*) FROM rooms WHERE created_by = ?"); $stmt->execute([$_SESSION['user_id']]); if ($stmt->fetchColumn() >= 3) { echo json_encode(['success' => false, 'error' => 'حداکثر ۳ اتاق میتوانید بسازید']); return; } $stmt = $pdo->prepare("INSERT INTO rooms (name, type, created_by) VALUES (?, ?, ?)"); $stmt->execute([$name, $type, $_SESSION['user_id']]); $roomId = $pdo->lastInsertId(); // Creator joins automatically $pdo->prepare("INSERT INTO room_members (room_id, user_id) VALUES (?, ?)") ->execute([$roomId, $_SESSION['user_id']]); echo json_encode(['success' => true, 'room' => ['id' => $roomId, 'name' => $name, 'type' => $type]]); } function getOnlineUsers($pdo) { $roomId = intval($_GET['room_id'] ?? 0); $stmt = $pdo->prepare(" SELECT COUNT(*) as count FROM users u JOIN room_members rm ON u.id = rm.user_id WHERE rm.room_id = ? AND u.status = 'online' AND u.last_active > DATE_SUB(NOW(), INTERVAL 5 MINUTE) "); $stmt->execute([$roomId]); $result = $stmt->fetch(); echo json_encode(['success' => true, 'count' => $result['count']]); } // Check if user is logged in $isLoggedIn = isset($_SESSION['user_id']); $currentUser = $isLoggedIn ? [ 'id' => $_SESSION['user_id'], 'username' => $_SESSION['username'], 'avatar' => $_SESSION['avatar'] ] : null; ?>
محلی امن و سریع برای گفتگو با دوستان و همکاران
با شماره موبایل و رمز عبور امن ثبتنام کنید. اطلاعات در دیتابیس ذخیره میشود
تا ۳ اتاق بسازید و با کاربران واقعی چت کنید. پیامها لحظهای ذخیره و نمایش داده میشوند
بروزرسانی خودکار هر ۳ ثانیه. مشاهده وضعیت آنلاین بودن کاربران