本文目录导读:

我来为您介绍一个PHP在线聊天与客服系统的完整解决方案。
核心功能架构
系统架构设计
/chat-system/
├── public/ # 前端资源
│ ├── index.html
│ ├── style.css
│ └── app.js
├── server/ # 后端代码
│ ├── chat.php # 聊天核心
│ ├── socket.php # WebSocket处理
│ └── config.php # 配置
├── database/ # 数据库
│ └── schema.sql
└── vendor/ # 第三方库
数据库设计
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE,
password VARCHAR(255),
role ENUM('customer', 'agent', 'admin'),
status ENUM('online', 'offline', 'busy'),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 聊天会话表
CREATE TABLE conversations (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT,
agent_id INT,
status ENUM('active', 'closed', 'pending'),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
closed_at TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES users(id),
FOREIGN KEY (agent_id) REFERENCES users(id)
);
-- 消息表
CREATE TABLE messages (
id INT PRIMARY KEY AUTO_INCREMENT,
conversation_id INT,
sender_id INT,
message TEXT,
type ENUM('text', 'image', 'file', 'system'),
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
readed BOOLEAN DEFAULT FALSE,
FOREIGN KEY (conversation_id) REFERENCES conversations(id)
);
核心PHP代码示例
chat.php - 主要聊天处理
<?php
require_once 'config.php';
class ChatSystem {
private $db;
public function __construct() {
$this->db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
}
// 发送消息
public function sendMessage($conversationId, $senderId, $message, $type = 'text') {
$stmt = $this->db->prepare("INSERT INTO messages (conversation_id, sender_id, message, type) VALUES (?, ?, ?, ?)");
$stmt->bind_param("iiss", $conversationId, $senderId, $message, $type);
if ($stmt->execute()) {
$messageId = $stmt->insert_id;
$this->notifyAgent($conversationId, $messageId);
return ['success' => true, 'message_id' => $messageId];
}
return ['success' => false];
}
// 获取新消息
public function getNewMessages($conversationId, $lastMessageId = 0) {
$stmt = $this->db->prepare("SELECT * FROM messages WHERE conversation_id = ? AND id > ? ORDER BY timestamp ASC");
$stmt->bind_param("ii", $conversationId, $lastMessageId);
$stmt->execute();
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
}
// 创建新会话
public function createConversation($customerId, $agentId = null) {
$stmt = $this->db->prepare("INSERT INTO conversations (customer_id, agent_id, status) VALUES (?, ?, 'active')");
$agentId = $agentId ?? $this->findAvailableAgent();
$stmt->bind_param("ii", $customerId, $agentId);
if ($stmt->execute()) {
return $stmt->insert_id;
}
return false;
}
// 查找空闲客服
private function findAvailableAgent() {
$result = $this->db->query("SELECT id FROM users WHERE role='agent' AND status='online' LIMIT 1");
if ($agent = $result->fetch_assoc()) {
return $agent['id'];
}
return null;
}
}
WebSocket实现(使用Ratchet)
<?php
require 'vendor/autoload.php';
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class ChatServer implements MessageComponentInterface {
protected $clients;
protected $users;
public function __construct() {
$this->clients = new \SplObjectStorage;
$this->users = [];
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
echo "New connection: {$conn->resourceId}\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
$data = json_decode($msg);
switch($data->type) {
case 'login':
$this->authenticateUser($from, $data);
break;
case 'message':
$this->handleMessage($from, $data);
break;
case 'typing':
$this->broadcastTyping($from, $data);
break;
}
}
private function handleMessage($from, $data) {
// 处理消息并转发给接收者
$recipient = $this->findRecipient($data->to);
if ($recipient) {
$recipient->send(json_encode([
'type' => 'message',
'from' => $this->users[$from->resourceId],
'message' => $data->message,
'time' => date('H:i:s')
]));
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
unset($this->users[$conn->resourceId]);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
}
前端实现(JavaScript)
class ChatClient {
constructor() {
this.ws = null;
this.userId = null;
this.conversationId = null;
this.lastMessageId = 0;
}
connect(serverUrl) {
this.ws = new WebSocket(serverUrl);
this.ws.onopen = () => {
console.log('Connected to chat server');
this.authenticate();
};
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
this.handleMessage(data);
};
this.ws.onclose = () => {
console.log('Disconnected');
setTimeout(() => this.connect(serverUrl), 3000);
};
}
sendMessage(message) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({
type: 'message',
message: message,
conversationId: this.conversationId
}));
}
}
handleMessage(data) {
switch(data.type) {
case 'message':
this.displayMessage(data);
break;
case 'typing':
this.showTypingIndicator(data.from);
break;
case 'system':
this.showNotification(data.message);
break;
}
}
displayMessage(data) {
const chatBox = document.getElementById('chat-messages');
const messageElement = document.createElement('div');
messageElement.className = data.from === this.userId ? 'message sent' : 'message received';
messageElement.innerHTML = `
<div class="message-content">${data.message}</div>
<div class="message-time">${data.time}</div>
`;
chatBox.appendChild(messageElement);
chatBox.scrollTop = chatBox.scrollHeight;
}
}
// 初始化客户端
const chat = new ChatClient();
chat.connect('ws://localhost:8080');
配置文件
<?php
// config.php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', 'password');
define('DB_NAME', 'chat_system');
define('UPLOAD_PATH', '/uploads/');
define('MAX_FILE_SIZE', 10485760); // 10MB
// 客服配置
define('MAX_CUSTOMERS_PER_AGENT', 5);
define('AUTO_ASSIGN', true);
define('OFFLINE_MESSAGE', true);
部署和运行
# 安装依赖 composer require cboden/ratchet # 启动WebSocket服务器 php server/socket.php # 或在Nginx/Apache中配置虚拟主机
高级功能建议
- 消息持久化:使用数据库存储历史消息
- 文件传输:支持图片、文档等文件上传
- 表情和快捷回复:预设回复模板
- 会话评分:客户对客服服务进行评价
- 统计分析:客服工作效率统计
- 多语言支持:国际化界面
- 机器人客服:简单问答自动回复
- 消息加密:端到端加密保证安全
安全注意事项
- 使用HTTPS/WSS加密传输
- 实施CSRF防护
- 输入验证和清理
- 会话管理安全
- 防止SQL注入
- 速率限制防止滥用
这个系统可以根据您的具体需求进行扩展和定制,适用于电商客服、技术支持、在线咨询等多种场景。