php聊天实现
PHP 聊天实现方法
使用 WebSocket 实现实时聊天
WebSocket 是实现实时聊天的理想选择。PHP 可以通过 Ratchet 库来创建 WebSocket 服务器。
安装 Ratchet:
composer require cboden/ratchet
创建 WebSocket 服务器:
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);
$server->run();
创建 Chat 类处理消息:
namespace MyApp;
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) {
$client->send($msg);
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$conn->close();
}
}
前端连接 WebSocket:
const conn = new WebSocket('ws://localhost:8080');
conn.onmessage = e => console.log(e.data);
conn.send('Hello');
使用 AJAX 轮询实现简单聊天
对于简单的聊天应用,可以使用 AJAX 轮询方式。
后端消息处理:
// save_message.php
$message = $_POST['message'];
file_put_contents('chat.txt', $message.PHP_EOL, FILE_APPEND);
// get_messages.php
echo file_get_contents('chat.txt');
前端实现:
setInterval(() => {
fetch('get_messages.php')
.then(r => r.text())
.then(messages => {
document.getElementById('chat').innerHTML = messages;
});
}, 1000);
document.getElementById('send').addEventListener('click', () => {
const message = document.getElementById('message').value;
fetch('save_message.php', {
method: 'POST',
body: new URLSearchParams({message})
});
});
使用数据库存储聊天记录
对于需要持久化存储的聊天应用,可以使用数据库。
创建消息表:
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
PHP 数据库操作:
// 保存消息
$pdo = new PDO('mysql:host=localhost;dbname=chat', 'user', 'pass');
$stmt = $pdo->prepare('INSERT INTO messages (user_id, message) VALUES (?, ?)');
$stmt->execute([$_SESSION['user_id'], $_POST['message']]);
// 获取消息
$stmt = $pdo->query('SELECT * FROM messages ORDER BY created_at DESC LIMIT 50');
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($messages);
实现用户认证
为聊天系统添加用户认证功能。
登录处理:
session_start();
if ($_POST['username'] && $_POST['password']) {
// 验证用户逻辑
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
}
检查登录状态:
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
实现私聊功能
扩展数据库结构支持私聊:
ALTER TABLE messages ADD COLUMN recipient_id INT NULL;
发送私聊消息:
$stmt = $pdo->prepare('INSERT INTO messages (user_id, recipient_id, message) VALUES (?, ?, ?)');
$stmt->execute([$_SESSION['user_id'], $_POST['recipient_id'], $_POST['message']]);
获取私聊消息:
$stmt = $pdo->prepare('SELECT * FROM messages
WHERE (user_id = ? AND recipient_id = ?)
OR (user_id = ? AND recipient_id = ?)
ORDER BY created_at DESC LIMIT 50');
$stmt->execute([
$_SESSION['user_id'],
$_GET['recipient_id'],
$_GET['recipient_id'],
$_SESSION['user_id']
]);
实现消息已读状态
添加已读标记字段:
ALTER TABLE messages ADD COLUMN is_read BOOLEAN DEFAULT FALSE;
标记消息为已读:
$pdo->prepare('UPDATE messages SET is_read = TRUE
WHERE recipient_id = ? AND user_id = ? AND is_read = FALSE')
->execute([$_SESSION['user_id'], $_GET['sender_id']]);
获取未读消息数:
$stmt = $pdo->prepare('SELECT COUNT(*) FROM messages
WHERE recipient_id = ? AND is_read = FALSE');
$stmt->execute([$_SESSION['user_id']]);
$unread = $stmt->fetchColumn();






