php 聊天功能实现
实现 PHP 聊天功能的方法
使用 WebSocket 实现实时聊天
WebSocket 是一种全双工通信协议,适合实现实时聊天功能。PHP 可以通过 Ratchet 库实现 WebSocket 服务器。
安装 Ratchet:
composer require cboden/ratchet
创建 WebSocket 服务器:
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
if ($client !== $from) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$conn->close();
}
}
$app = new Ratchet\App('localhost', 8080);
$app->route('/chat', new Chat, ['*']);
$app->run();
前端连接代码:
const conn = new WebSocket('ws://localhost:8080/chat');
conn.onmessage = e => console.log(e.data);
conn.send('Hello');
使用 AJAX 轮询实现简单聊天
对于不需要实时性的简单聊天,可以使用 AJAX 轮询方式。
保存聊天消息到数据库:
// 保存消息
$message = $_POST['message'];
$stmt = $pdo->prepare("INSERT INTO messages (content) VALUES (?)");
$stmt->execute([$message]);
获取消息的 API:
// 获取消息
$stmt = $pdo->query("SELECT * FROM messages ORDER BY id DESC LIMIT 50");
echo json_encode($stmt->fetchAll());
前端轮询代码:
setInterval(() => {
fetch('/get-messages.php')
.then(res => res.json())
.then(messages => {
// 显示消息
});
}, 3000);
使用 PHP 和 MySQL 存储聊天记录
创建消息表:
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30),
message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
插入新消息:
$stmt = $pdo->prepare("INSERT INTO messages (username, message) VALUES (?, ?)");
$stmt->execute([$username, $message]);
实现私聊功能
为私聊消息添加接收者字段:
ALTER TABLE messages ADD COLUMN receiver VARCHAR(30);
查询私聊消息:
$stmt = $pdo->prepare("
SELECT * FROM messages
WHERE (username = ? AND receiver = ?)
OR (username = ? AND receiver = ?)
ORDER BY created_at
");
$stmt->execute([$user1, $user2, $user2, $user1]);
添加消息加密
使用 OpenSSL 加密消息:
$encrypted = openssl_encrypt(
$message,
'AES-256-CBC',
$key,
0,
$iv
);
解密消息:
$decrypted = openssl_decrypt(
$encrypted,
'AES-256-CBC',
$key,
0,
$iv
);
实现文件传输
保存上传的文件:
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["file"]["name"]);
move_uploaded_file($_FILES["file"]["tmp_name"], $targetFile);
记录文件消息:
$stmt = $pdo->prepare("
INSERT INTO messages (username, message, file_path)
VALUES (?, ?, ?)
");
$stmt->execute([$username, '发送了文件', $targetFile]);
用户在线状态管理
创建在线用户表:
CREATE TABLE online_users (
username VARCHAR(30) PRIMARY KEY,
last_seen TIMESTAMP
);
更新用户在线状态:
$stmt = $pdo->prepare("
INSERT INTO online_users (username, last_seen)
VALUES (?, NOW())
ON DUPLICATE KEY UPDATE last_seen = NOW()
");
$stmt->execute([$username]);
获取在线用户:
$stmt = $pdo->query("
SELECT username FROM online_users
WHERE last_seen > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
");






