php实现站内私信功能
实现站内私信功能
数据库设计
创建私信相关的数据表,通常包括用户表和私信表。用户表存储用户信息,私信表存储消息内容。
用户表(users)结构示例:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
私信表(messages)结构示例:
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id INT NOT NULL,
receiver_id INT NOT NULL,
message TEXT NOT NULL,
is_read BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id),
FOREIGN KEY (receiver_id) REFERENCES users(id)
);
发送私信功能
创建一个表单用于发送私信,表单提交后处理发送逻辑。
发送私信表单示例:
<form action="send_message.php" method="post">
<input type="hidden" name="receiver_id" value="<?php echo $receiver_id; ?>">
<textarea name="message" placeholder="输入消息内容"></textarea>
<button type="submit">发送</button>
</form>
发送私信处理(send_message.php):
<?php
session_start();
require_once 'db_connection.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SESSION['user_id'])) {
$sender_id = $_SESSION['user_id'];
$receiver_id = $_POST['receiver_id'];
$message = trim($_POST['message']);
if (!empty($message)) {
$stmt = $pdo->prepare("INSERT INTO messages (sender_id, receiver_id, message) VALUES (?, ?, ?)");
$stmt->execute([$sender_id, $receiver_id, $message]);
header("Location: messages.php?success=1");
exit;
}
}
header("Location: messages.php?error=1");
exit;
?>
查看私信功能
创建一个页面用于显示用户收到的私信列表。
私信列表页面(messages.php):
<?php
session_start();
require_once 'db_connection.php';
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
$user_id = $_SESSION['user_id'];
$stmt = $pdo->prepare("SELECT m.*, u.username as sender_name FROM messages m JOIN users u ON m.sender_id = u.id WHERE m.receiver_id = ? ORDER BY m.created_at DESC");
$stmt->execute([$user_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head>
<title>我的私信</title>
</head>
<body>
<h1>收到的私信</h1>
<?php foreach ($messages as $message): ?>
<div>
<p>来自: <?php echo htmlspecialchars($message['sender_name']); ?></p>
<p>内容: <?php echo htmlspecialchars($message['message']); ?></p>
<p>时间: <?php echo $message['created_at']; ?></p>
</div>
<?php endforeach; ?>
</body>
</html>
标记已读功能
在查看私信时,可以添加标记已读的功能。
更新私信为已读:
$stmt = $pdo->prepare("UPDATE messages SET is_read = TRUE WHERE id = ? AND receiver_id = ?");
$stmt->execute([$message_id, $user_id]);
实时通知
使用Ajax轮询或WebSocket实现新消息实时通知。
Ajax轮询示例:
setInterval(function() {
$.ajax({
url: 'check_new_messages.php',
success: function(response) {
if (response.count > 0) {
$('#notification').text('你有 ' + response.count + ' 条新消息');
}
}
});
}, 5000);
检查新消息(check_new_messages.php):
<?php
session_start();
require_once 'db_connection.php';
if (!isset($_SESSION['user_id'])) {
exit;
}
$user_id = $_SESSION['user_id'];
$stmt = $pdo->prepare("SELECT COUNT(*) as count FROM messages WHERE receiver_id = ? AND is_read = FALSE");
$stmt->execute([$user_id]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
header('Content-Type: application/json');
echo json_encode($result);
?>
安全性考虑
对用户输入进行过滤和验证,防止SQL注入和XSS攻击。
$message = filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING);
使用预处理语句防止SQL注入,对输出内容使用htmlspecialchars()防止XSS攻击。
echo htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
性能优化
为频繁查询的字段添加索引,例如receiver_id和is_read字段。
CREATE INDEX idx_receiver ON messages(receiver_id);
CREATE INDEX idx_read_status ON messages(is_read);
对于大量消息,实现分页功能减轻数据库压力。

$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = 10;
$offset = ($page - 1) * $limit;
$stmt = $pdo->prepare("SELECT m.*, u.username as sender_name FROM messages m JOIN users u ON m.sender_id = u.id WHERE m.receiver_id = ? ORDER BY m.created_at DESC LIMIT ? OFFSET ?");
$stmt->execute([$user_id, $limit, $offset]);





