Live Chat Button on Modern Computer Keyboard. (v5)
Okay, here’s a comprehensive guide on building a real-time website chat script using PHP, HTML, CSS, JavaScript, and MySQL. This outlines the core components and logic involved.
Project Structure:
We will create a basic directory structure for clarity:
root/
css/
style.css
js/
script.js
php/
db_connect.php
get_messages.php
send_message.php
login.php
logout.php
register.php
online_users.php
index.php
1. Database Setup (MySQL):
First, you’ll need a database to store user information and chat messages. Create a database (e.g., chat_db
) and the following tables:
users
table:CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, -- Store hashed passwords last_active TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
messages
table:
CREATE TABLE messages ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, message TEXT NOT NULL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) );
2. Database Connection (php/db_connect.php
):
This file establishes a connection to your MySQL database.
<?php $servername = "localhost"; // Or your server address $username = "your_username"; $password = "your_password"; $dbname = "chat_db"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } //Set default time zone date_default_timezone_set('UTC'); ?>
Important: Replace "your_username"
, "your_password"
, and "chat_db"
with your actual database credentials. Never hardcode sensitive information like database credentials directly into public-facing code in a production environment. Use environment variables or configuration files.
3. User Authentication (Login, Registration, Logout):
php/register.php
:<?php require_once 'db_connect.php'; if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = $_POST["username"]; $password = $_POST["password"];// Basic validation (add more robust validation) if (empty($username) || empty($password)) { echo json_encode(['status' => 'error', 'message' => 'Username and password are required.']); exit; } // Check if username already exists $check_sql = "SELECT id FROM users WHERE username = ?"; $check_stmt = $conn->prepare($check_sql); $check_stmt->bind_param("s", $username); $check_stmt->execute(); $check_stmt->store_result(); if ($check_stmt->num_rows > 0) { echo json_encode(['status' => 'error', 'message' => 'Username already exists.']); $check_stmt->close(); exit; } $check_stmt->close(); // Hash the password $hashed_password = password_hash($password, PASSWORD_DEFAULT); // Insert the user into the database $sql = "INSERT INTO users (username, password) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $username, $hashed_password); if ($stmt->execute()) { echo json_encode(['status' => 'success', 'message' => 'Registration successful.']); } else { echo json_encode(['status' => 'error', 'message' => 'Registration failed: ' . $conn->error]); } $stmt->close(); $conn->close(); } else { echo json_encode(['status' => 'error', 'message' => 'Invalid request.']); } ?>
php/login.php
:
<?php require_once 'db_connect.php'; session_start(); // Start the session if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = $_POST["username"]; $password = $_POST["password"];if (empty($username) || empty($password)) { echo json_encode(['status' => 'error', 'message' => 'Username and password are required.']); exit; } $sql = "SELECT id, password FROM users WHERE username = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("s", $username); $stmt->execute(); $stmt->store_result(); if ($stmt->num_rows == 1) { $stmt->bind_result($user_id, $hashed_password); $stmt->fetch(); if (password_verify($password, $hashed_password)) { // Password is correct $_SESSION["user_id"] = $user_id; // Store user ID in session //Update last_active timestamp $update_sql = "UPDATE users SET last_active = CURRENT_TIMESTAMP WHERE id = ?"; $update_stmt = $conn->prepare($update_sql); $update_stmt->bind_param("i", $user_id); $update_stmt->execute(); $update_stmt->close(); echo json_encode(['status' => 'success', 'message' => 'Login successful.']); } else { echo json_encode(['status' => 'error', 'message' => 'Invalid username or password.']); } } else { echo json_encode(['status' => 'error', 'message' => 'Invalid username or password.']); } $stmt->close(); $conn->close(); } else { echo json_encode(['status' => 'error', 'message' => 'Invalid request.']); } ?>
php/logout.php
:
<?php session_start(); session_unset(); session_destroy(); echo json_encode(['status' => 'success', 'message' => 'Logged out.']); exit; ?>
index.php
(HTML – Login/Registration Form):
<!DOCTYPE html> <html> <head> <title>Chat</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div id="login-register-container"> <div id="login-form"> <h2>Login</h2> <input type="text" id="login-username" placeholder="Username"><br> <input type="password" id="login-password" placeholder="Password"><br> <button id="login-button">Login</button> <p id="login-message"></p> </div> <div id="register-form"> <h2>Register</h2> <input type="text" id="register-username" placeholder="Username"><br> <input type="password" id="register-password" placeholder="Password"><br> <button id="register-button">Register</button> <p id="register-message"></p> </div> </div> <div id="chat-container" style="display:none;"> <div id="chat-messages"></div> <input type="text" id="message-input" placeholder="Type your message..."> <button id="send-button">Send</button> <button id="logout-button">Logout</button> <div id="online-users"></div> </div> <script src="js/script.js"></script> </body> </html>
4. Chat Functionality (Sending, Retrieving, Displaying Messages):
php/send_message.php
:<?php session_start(); require_once 'db_connect.php'; if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_SESSION["user_id"])) { $user_id = $_SESSION["user_id"]; $message = $_POST["message"];if (empty($message)) { echo json_encode(['status' => 'error', 'message' => 'Message cannot be empty.']); exit; } $sql = "INSERT INTO messages (user_id, message) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("is", $user_id, $message); if ($stmt->execute()) { echo json_encode(['status' => 'success', 'message' => 'Message sent.']); } else { echo json_encode(['status' => 'error', 'message' => 'Failed to send message: ' . $conn->error]); } $stmt->close(); $conn->close(); } else { echo json_encode(['status' => 'error', 'message' => 'Invalid request.']); } ?>
php/get_messages.php
:
<?php require_once 'db_connect.php'; $last_message_id = isset($_GET['last_message_id']) ? intval($_GET['last_message_id']) : 0; $sql = "SELECT messages.id, messages.message, messages.timestamp, users.username FROM messages INNER JOIN users ON messages.user_id = users.id WHERE messages.id > ? ORDER BY messages.timestamp ASC"; $stmt = $conn->prepare($sql); $stmt->bind_param('i', $last_message_id); $stmt->execute(); $result = $stmt->get_result(); $messages = array(); while ($row = $result->fetch_assoc()) { $messages[] = $row; } echo json_encode($messages); $stmt->close(); $conn->close(); ?>
php/online_users.php
:
<?php require_once 'db_connect.php'; // Set inactivity threshold (e.g., 5 minutes = 300 seconds) $inactivity_threshold = 300; // Calculate the timestamp for inactive users $inactive_timestamp = date('Y-m-d H:i:s', time() - $inactivity_threshold); // Query to get online users (last_active within the threshold) $sql = "SELECT id, username FROM users WHERE last_active >= ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("s", $inactive_timestamp); // Binding as string because it it's a datetime $stmt->execute(); $result = $stmt->get_result(); $online_users = array(); while ($row = $result->fetch_assoc()) { $online_users[] = $row; } echo json_encode($online_users); $stmt->close(); $conn->close(); ?>
5. JavaScript (js/script.js
): This file handles the client-side logic, including AJAX requests to your PHP scripts.
document.addEventListener('DOMContentLoaded', function() { let loginForm = document.getElementById('login-form'); let registerForm = document.getElementById('register-form'); let chatContainer = document.getElementById('chat-container'); let loginButton = document.getElementById('login-button'); let registerButton = document.getElementById('register-button'); let logoutButton = document.getElementById('logout-button'); let sendMessageButton = document.getElementById('send-button'); let loginMessage = document.getElementById('login-message'); let registerMessage = document.getElementById('register-message'); let chatMessages = document.getElementById('chat-messages'); let messageInput = document.getElementById('message-input'); let onlineUsersDiv = document.getElementById('online-users'); let lastMessageId = 0; // Keep track of the last message ID // ---- Authentication Functions ---- function login(username, password) { fetch('php/login.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `username=${username}&password=${password}` }) .then(response => response.json()) .then(data => { if (data.status === 'success') { loginForm.style.display = 'none'; registerForm.style.display = 'none'; chatContainer.style.display = 'block'; loginMessage.textContent = ''; //Start fetching messages and online users lastMessageId = 0; // Reset when logging in loadMessages(); loadOnlineUsers(); //Start periodic updates setInterval(loadMessages, 2000); // Refresh messages every 2 seconds setInterval(loadOnlineUsers, 15000); // Refresh online users every 15 seconds. } else { loginMessage.textContent = data.message; } }) .catch(error => { console.error('Login error:', error); loginMessage.textContent = 'Login failed.'; }); } function register(username, password) { fetch('php/register.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `username=${username}&password=${password}` }) .then(response => response.json()) .then(data => { registerMessage.textContent = data.message; }) .catch(error => { console.error('Registration error: ', error); registerMessage.textContent = 'Registration failed.'; }); } function logout() { fetch('php/logout.php') .then(response => response.json()) .then(data => { if (data.status === 'success') { chatContainer.style.display = 'none'; loginForm.style.display = 'block'; registerForm.style.display = 'block'; chatMessages.innerHTML = ''; // Clear messages onlineUsersDiv.innerHTML = ''; //Clear online users } }) .catch(error => console.error('Logout error:', error)); } // ---- Chat Functions ---- function sendMessage(message) { fetch('php/send_message.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `message=${message}` }) .then(response => response.json()) .then(data => { if (data.status === 'success') { messageInput.value = ''; // Clear the input //loadMessages(); //Refresh messages - No need with automatic loading } else { console.error('Send message error: ', data.message); } }) .catch(error => console.error('Send message error:', error)); } function loadMessages() { fetch(`php/get_messages.php?last_message_id=${lastMessageId}`) .then(response => response.json()) .then(data => { if (data.length > 0) { data.forEach(message => { const messageDiv = document.createElement('div'); messageDiv.classList.add('message'); messageDiv.innerHTML = `<strong>${message.username}:</strong> ${message.message} <span class="timestamp">(${message.timestamp})</span>`; // Include timestamp chatMessages.appendChild(messageDiv); lastMessageId = message.id; //Update the last ID }); // Scroll to the bottom of chat chatMessages.scrollTop = chatMessages.scrollHeight; } }) .catch(error => console.error('Load messages error:', error)); } function loadOnlineUsers() { fetch('php/online_users.php') .then(response => response.json()) .then(data => { onlineUsersDiv.innerHTML = '<h3>Online Users:</h3>'; //Clear previous list if(data.length > 0) { let userList = '<ul>'; data.forEach(user => { userList += `<li>${user.username}</li>` }); userList += '</ul>'; onlineUsersDiv.innerHTML += userList; } else { onlineUsersDiv.innerHTML += '<p>No users online.</p>'; } }) .catch(error => console.error('Load online users error: ', error)); } // ---- Event Listeners ---- loginButton.addEventListener('click', function() { login(document.getElementById('login-username').value, document.getElementById('login-password').value); }); registerButton.addEventListener('click', function() { register(document.getElementById('register-username').value, document.getElementById('register-password').value); }); logoutButton.addEventListener('click', logout); sendMessageButton.addEventListener('click', function() { sendMessage(messageInput.value); }); messageInput.addEventListener('keydown', function(event) { if (event.key === 'Enter') { sendMessage(messageInput.value); } }); });
6. CSS (css/style.css
):
Provide styling to make the chat interface visually appealing. Here’s a basic example:
body { font-family: sans-serif; margin: 0; padding: 0; background-color: #f4f4f4; } #login-register-container { width: 400px; margin: 50px auto; background-color: #fff; padding: 20px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } #login-form, #register-form { margin-bottom: 20px; } h2 { text-align: center; color: #333; } input[type="text"], input[type="password"] { width: 90%; padding: 10px; margin-bottom: 10px; border: 1px solid #ddd; border-radius: 4px; } button { background-color: #5cb85c; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; width: 100%; } button:hover { background-color: #449d44; } #chat-container { width: 600px; margin: 50px auto; background-color: #fff; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); padding: 20px; } #chat-messages { height: 300px; overflow-y: scroll; padding: 10px; border: 1px solid #ddd; margin-bottom: 10px; } #chat-messages .message { margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #eee; } #chat-messages .message .timestamp { font-size: 0.8em; color: #888; margin-left: 5px; } #message-input { width: 75%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; margin-right: 10px; } #send-button, #logout-button{ width: 20%; } #online-users { margin-top: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; } #online-users ul { list-style-type: none; padding: 0; } #online-users li { margin-bottom: 5px; }
Key Considerations and Improvements:
password_hash()
to securely store passwords and password_verify()
to compare them.session_regenerate_id()
periodically.htmlspecialchars()
or strip_tags()
to escape special characters.This detailed walkthrough provides a foundation for building a real-time website chat script. Remember to adapt and expand upon it based on your specific requirements. Remember to address the “Key Considerations and Improvements” points to create a secure, efficient, and user-friendly chat application.
WordPress development has evolved significantly, and modern tooling plays a crucial role in creating efficient…
I. Project Overview The goal is to automate the process of notifying search engines (like…
1. Database Structure (MySQL) We'll need a database table to store information about our website's…
This explanation aims to provide a solid foundation for understanding the process and implementing your…
Comprehensive guide on creating a simple website analytics system using PHP, HTML, CSS, JavaScript, and…
I. Database Setup (MySQL) The first step is setting up a database to store file…