php实现站内私信功能
数据库设计
创建两个表用于存储私信数据。messages表存储私信内容,message_status表存储阅读状态。
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id INT NOT NULL,
receiver_id INT NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id),
FOREIGN KEY (receiver_id) REFERENCES users(id)
);
CREATE TABLE message_status (
id INT AUTO_INCREMENT PRIMARY KEY,
message_id INT NOT NULL,
user_id INT NOT NULL,
is_read BOOLEAN DEFAULT FALSE,
FOREIGN KEY (message_id) REFERENCES messages(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
发送私信功能
创建发送私信的PHP处理脚本,验证用户身份并插入数据。

<?php
session_start();
require 'db_connect.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SESSION['user_id'])) {
$senderId = $_SESSION['user_id'];
$receiverId = filter_input(INPUT_POST, 'receiver_id', FILTER_VALIDATE_INT);
$content = trim(filter_input(INPUT_POST, 'content', FILTER_SANITIZE_STRING));
if ($receiverId && $content) {
try {
$stmt = $pdo->prepare("INSERT INTO messages (sender_id, receiver_id, content) VALUES (?, ?, ?)");
$stmt->execute([$senderId, $receiverId, $content]);
$messageId = $pdo->lastInsertId();
$stmt = $pdo->prepare("INSERT INTO message_status (message_id, user_id) VALUES (?, ?)");
$stmt->execute([$messageId, $receiverId]);
echo json_encode(['status' => 'success']);
} catch (PDOException $e) {
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
}
}
?>
获取私信列表
实现获取用户私信列表的功能,包括未读消息标记。
<?php
session_start();
require 'db_connect.php';
if (isset($_SESSION['user_id'])) {
$userId = $_SESSION['user_id'];
$stmt = $pdo->prepare("
SELECT m.*, u.username as sender_name, ms.is_read
FROM messages m
JOIN users u ON m.sender_id = u.id
JOIN message_status ms ON m.id = ms.message_id AND ms.user_id = ?
WHERE m.receiver_id = ?
ORDER BY m.created_at DESC
");
$stmt->execute([$userId, $userId]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
header('Content-Type: application/json');
echo json_encode($messages);
}
?>
标记为已读
当用户查看私信时,更新阅读状态。

<?php
session_start();
require 'db_connect.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SESSION['user_id'])) {
$messageId = filter_input(INPUT_POST, 'message_id', FILTER_VALIDATE_INT);
$userId = $_SESSION['user_id'];
if ($messageId) {
$stmt = $pdo->prepare("UPDATE message_status SET is_read = TRUE WHERE message_id = ? AND user_id = ?");
$stmt->execute([$messageId, $userId]);
echo json_encode(['status' => 'success']);
}
}
?>
前端交互示例
使用jQuery实现简单的AJAX交互。
// 发送私信
$('#send-message-form').submit(function(e) {
e.preventDefault();
$.post('send_message.php', $(this).serialize(), function(response) {
if (response.status === 'success') {
$('#message-content').val('');
loadMessages();
}
}, 'json');
});
// 加载私信列表
function loadMessages() {
$.get('get_messages.php', function(messages) {
let html = '';
messages.forEach(msg => {
html += `<div class="message ${msg.is_read ? '' : 'unread'}">
<strong>${msg.sender_name}</strong>
<p>${msg.content}</p>
<small>${new Date(msg.created_at).toLocaleString()}</small>
</div>`;
});
$('#messages-container').html(html);
}, 'json');
}
// 标记为已读
$(document).on('click', '.message', function() {
const messageId = $(this).data('id');
$.post('mark_as_read.php', {message_id: messageId});
});
安全注意事项
验证用户身份和权限,防止跨站请求伪造(CSRF)。
// 在所有处理脚本开头添加
if (!isset($_SESSION['user_id'])) {
header('HTTP/1.1 403 Forbidden');
exit;
}
// 在表单中添加CSRF令牌
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
// 验证CSRF令牌
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
header('HTTP/1.1 403 Forbidden');
exit;
}




