PHP项目在线聊天与客服系统

wen PHP项目 2

本文目录导读:

PHP项目在线聊天与客服系统

  1. 核心功能架构
  2. 高级功能建议
  3. 安全注意事项

我来为您介绍一个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中配置虚拟主机

高级功能建议

  1. 消息持久化:使用数据库存储历史消息
  2. 文件传输:支持图片、文档等文件上传
  3. 表情和快捷回复:预设回复模板
  4. 会话评分:客户对客服服务进行评价
  5. 统计分析:客服工作效率统计
  6. 多语言支持:国际化界面
  7. 机器人客服:简单问答自动回复
  8. 消息加密:端到端加密保证安全

安全注意事项

  • 使用HTTPS/WSS加密传输
  • 实施CSRF防护
  • 输入验证和清理
  • 会话管理安全
  • 防止SQL注入
  • 速率限制防止滥用

这个系统可以根据您的具体需求进行扩展和定制,适用于电商客服、技术支持、在线咨询等多种场景。

抱歉,评论功能暂时关闭!