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.cssjs/ script.jsphp/ db_connect.phpget_messages.phpsend_message.phplogin.phplogout.phpregister.phponline_users.phpindex.php1. 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.
This guide provides a detailed walkthrough of installing and configuring an Apache web server and…
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…