资讯动态

PHPlivechat 修复版部署实战:PHP 在线客服系统无限坐席与手机 APP 接入

发布时间:2026/10/18 7:22:58 来源:尧图企业网站定制
简介这是2021年12月修复版的PHPlivechat在线客服系统主打无限坐席集PHP源码、安卓客服端APP与搭建教程于一体。系统面向有自建客服需求的网站站长、PHP开发者以及中小企业可部署于常见Apache/PHP环境只需一台服务器即可应对售前售后咨询也适合开发者研究WebIM多端通信架构。资源包共451个文件、约133.83MB其中包含122个JS、100个PHP、110个PNG以及HTML/CSS、音频、SQL等文件PHP实现业务逻辑JS/CSS支撑前端交互与界面样式MP3用作提示音SQL为数据库结构另有APK手机客户端、.htaccess伪静态配置和多种图标字体文件资源还提供PC端与手机端两套界面样式便于自定义外观。已有1107人学习下载。无论想直接部署一套可用的在线客服系统还是参考多端客服通信、扫码绑定APP的实现方案这套源码都能给出一份完整的参考后台可视化、手机端联动、聊天链接集成等一应俱全。1. PHPlivechat 2021年12月修复版为什么这个开源 PHP 在线客服系统突然又值得用了自建在线客服系统的团队往往卡在一个尴尬点商业 SaaS 按坐席收费一年下来不少钱而开源方案里能同时满足「PHP 技术栈、支持多坐席、有手机端」的选项并不多。PHPlivechat 是这个领域里绕不开的名字一个用 PHP 写的开源在线客服系统访客端网页发起对话坐席端网页接收回复支持多坐席分配。标题里的 2021 年 12 月修复版解决的不是加了什么炫酷功能而是把老代码从 PHP 5.x 时代拽到了现代环境里让它在 PHP 7.x 甚至部分 8.x 环境下不再翻车。这个修复版的价值点在于三个坐席数量不再被旧授权逻辑卡死官方体系里原本受限的坐席数被放开补上了手机 APP 客服端的可用接口——老版本里 APP 基本是个摆设登录鉴权和会话推送都存在问题附带完整的部署教程把新手最容易卡住的数据库初始化、目录权限、伪静态配置都讲清楚了。适合谁用预算有限但有 PHP 运维能力的中小团队比如电商售前售后、外贸独立站、SaaS 产品内嵌帮助台。对纯业务人员来说门槛偏高但只要有一个人能改 PHP 配置这套系统就能省下每年大几千的坐席费。我先把话放在前面这套系统毕竟有年头网上流传的版本五花八门装的时候经常在同一个地方踩坑。这篇文章不是从零教 PHP而是把「从下载到跑通、到放开坐席、到手机 APP 能用」这条路上所有我踩过的坑和确认过能用的做法整理一遍。2. 先把最小系统跑起来PHP 环境、数据库与首次登录2.1 环境选型为什么 PHP 7.4 MySQL 5.7 是稳妥基线PHPlivechat 的代码写得很早最早一批用户跑在 PHP 5.2 上。但 PHP 5.x 现在连官方都不维护了安全漏洞没人补所以这版修复版的目标运行环境基本锁定在 PHP 7.x。我的建议是 PHP 7.4这是 7.x 系列里生命周期最长的版本也是对老代码兼容性最好的一个。PHP 8.0 之后有两个问题一是很多老代码里用的mysql_*函数早就删了虽然这版修复版已经改成mysqli或PDO但难免有漏网之鱼二是 PHP 8 对报错级别更敏感老代码里常见的「未定义索引」类提示在 PHP 8 里直接变成 Warning 甚至异常表现就是页面白屏。MySQL 用 5.7 就好。MariaDB 10.x 也可以但如果你用的是 MySQL 8.0注意认证插件问题PHP 7.4 的mysqli扩展默认用的mysql_native_password在 MySQL 8.0 里默认没开启连不上数据库时大概率就是这个问题。部署前先确认环境php -v # 期望输出 PHP 7.4.x php -m | grep -E pdo_mysql|mysqli|curl|openssl # 这四样缺一不可缺了先去装扩展 mysql --version # 期望输出 5.7.x 或 10.xMariaDB这里curl和openssl容易被忽略。手机 APP 登录、消息推送都要走 HTTP 接口如果 PHP 没开 curl 扩展后面 APP 对接时怎么调都调不通。确认完环境再继续后面所有操作都建立在 PHP 7.4 MySQL 5.7 这个基线上。2.2 下载解压与目录结构检查下载后拿到的是一个 zip 或 tar.gz 包解压后放到 Web 根目录。常见做法是在 Nginx 的 root 指向的目录下建一个子目录比如/var/www/kefu/。解压后先别急着访问先看目录结构unzip phplivechat_fixed_202112.zip -d /var/www/kefu/ cd /var/www/kefu/ ls -la # 重点看是否存在 install.sql 或 database.sql 之类的数据库脚本 # 是否存在 config.php 或 include/config.php 之类的配置文件目录结构每个版本略有差异但有两个东西一定要找到数据库初始化脚本和项目配置文件。数据库脚本一般叫install.sql、database.sql、db.sql之类配置文件可能是config.php、include/config.php、application/config/database.php。不是所有版本都自带配置文件有些版本是在安装向导里填数据库信息运行时会自动生成配置文件。如果解压出来发现没有任何 SQL 文件和配置文件那很可能是没解压完整或者下载的包本身就是残缺版直接换一个下载来源。解压完成后立刻做一件事检查config.php是否存在检查install.sql是否存在。存在就继续不存在就换包。2.3 数据库初始化导入 SQL 与配置文件修改数据库脚本导入是最容易出问题的一步很多人导入失败是因为编码不对。用命令行导入比用 phpMyAdmin 导入更不容易翻车mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS livechat DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql -uroot -p livechat /var/www/kefu/install.sqlutf8mb4比老的utf8强在能存 emoji手机端聊天记录里表情符号很常见用utf8导入后会变成乱码问号。导入成功后打开配置文件把数据库连接信息改成自己的// config.php 或 application/config/database.php视具体版本而定 $db_host 127.0.0.1; $db_user root; $db_pass 你的数据库密码; $db_name livechat; $db_port 3306; $db_prefix ; // 部分版本还需要配置站点URL注意结尾不要带斜杠 $site_url http://你的域名.com;配置完成后重启 PHP-FPM 和 Nginxsystemctl restart php7.4-fpm systemctl restart nginx注意 PHP-FPM 需要配置好与 Nginx 的 socket 通信常见路径是unix:/run/php/php7.4-fpm.sock。这个路径如果你不确定可以在/etc/nginx/sites-enabled/里找到站点配置确认或者直接看php-fpm的进程启动日志。2.4 首次登录与验证系统跑通数据库导入成功后打开浏览器访问站点首页正常情况下会看到访客端对话窗口。首次登录坐席后台默认管理员账号密码通常在install.sql里或安装文档里有写。常见写死在 SQL 里的初始账号是admin/admin123但不同版本不一样。如果你导入 SQL 后登录页面提示账号密码错误直接去数据库里改-- 查看管理员表结构和已有账号 USE livechat; SHOW TABLES; SELECT * FROM users WHERE type admin OR role admin; -- 找到管理员账号后更新密码。密码字段通常是MD5加密 UPDATE users SET password MD5(你设置的新密码) WHERE id 1;这里有个血泪经验不要用 PHP 自带的password_hash函数生成的密码去覆盖老系统代码里验证密码用的是md5()函数你新生成的哈希验不过。先看代码里怎么验密码再决定怎么生成新密码。登录进去之后先在「设置」里确认站点 URL 配置正确然后在访客端页面发一条测试消息坐席后台如果能收到最小系统就算跑通了。这一步成功说明环境、数据库、配置三条线全通后面改坐席数、接 APP 都建立在「系统能跑」这个前提上。3. 坐席数放开到「无限」从代码层面看坐席限制在哪里3.1 坐席数校验点先找到限制写在哪个文件标题重点提到「无限坐席」要理解这个「无限」是怎么来的。老版本 PHPlivechat 对坐席数量有一套授权校验逻辑常见做法是在代码里写死一个上限值比如MAX_AGENTS 3并在登录或创建坐席时检查人数。修复版要做的事就是把这个上限去掉但具体是改数据库字段还是改代码逻辑因版本而异。先动手找出限制在哪。最常见的校验位置有两个一个是数据库配置表里存一个数值比如settings表里的max_agents字段另一个是 PHP 代码里写死的常量或者 if 判断。用 grep 搜索是最高效的方式cd /var/www/kefu/ grep -rn max_agent --include*.php | head -20 grep -rn agent_limit\|MAX_AGENT --include*.php | head -20如果 grep 到了结果比如if ($agent_count $max_agents) { die(达到坐席上限); }这类代码那限制就在代码里。把判断条件去掉或把上限值改大即可。如果 grep 不到去数据库里查USE livechat; SHOW TABLES LIKE %setting%; SELECT * FROM settings WHERE setting_name LIKE %agent% OR setting_name LIKE %limit%;查出来的字段值改成 0 或 999999。注意改数据库后可能需要清缓存有些系统会把查询结果缓存到文件里直接在数据目录下找缓存文件删掉或重启 PHP-FPM 也可以。3.2 修改坐席上限的实操两种场景分别处理场景一限制在数据库。这种最简单SQL 直接更新即可UPDATE settings SET setting_value 999999 WHERE setting_name max_agents;改完后验证方式进后台 → 坐席管理 → 添加坐席如果能连续添加超过原来的限制数说明已生效。场景二限制在代码。假设找到的是类似这样的逻辑// 伪代码展示常见写法 $max_agents 3; $current_agents $db-query(SELECT COUNT(*) FROM users WHERE roleagent)-fetchColumn(); if ($current_agents $max_agents) { exit(Agent limit reached); }最省事的改法是直接把$max_agents 3;改成$max_agents 100000;。但如果你希望以后能直接在后台调整可以改成从数据库读取// 从 settings 表读取坐席上限不存在时默认 100000 $max_agents $db-query(SELECT setting_value FROM settings WHERE setting_namemax_agents)-fetchColumn(); if (!$max_agents) { $max_agents 100000; }这算是一个更优雅的做法逻辑上等价于去掉限制但保留了以后调回来的余地。改完代码记得检查 PHP 语法php -l /var/www/kefu/你修改的文件.php后面这句是常识但值得说改完代码没生效八成是 OPcache 缓存了旧代码systemctl restart php7.4-fpm重启一下就好。这套组合拳打下来坐席数量就不再是问题了。3.3 「无限坐席」不等于「无限并发」理性看待这个上限必须泼一盆冷水代码层面的坐席数放开只是去掉了账号数量的限制不代表你可以真的开几千个坐席同时在线。PHPlivechat 的消息传递机制老版本普遍用轮询也就是每个坐席的浏览器每隔几秒向服务器发一次 HTTP 请求去拉新消息。假设置 3 秒轮询一次100 个坐席同时在线上平均每秒大约 33 个请求如果是 MySQL 直连方式连接数很容易被打满。所以标题里的「无限坐席」更适合的理解是不再限制你建立坐席账号的数量但并发承载上限取决于服务器性能和架构。对于中小团队同时在线坐席几十个以内装好后不用太操心如果真要往上百坐席走建议做两件事一是把轮询间隔从 3 秒改成 5 秒缓解请求频率二是检查 PHP-FPM 的进程数是否足够之后在最后一步进阶章节里细说。不要跟老板保证「无限坐席随便开」老板当真了上线当天就玩火。4. 手机 APP 客服端接入接口协议、登录态与消息同步4.1 APP 客服端的技术前提老系统的 REST 接口在哪里这一版最值钱的升级是「带手机 APP 客服端」。手机客服端的核心诉求是坐席不在电脑前时用手机也能看到访客消息、能回复、能接收新会话提醒。老版本的 APP 很多时候是半个残废——能登录但收不到消息原因在于老代码的消息推送依赖 WebSocket 或者 Server Push而 APP 环境里这套不通。修复版的做法通常是把这些接口改成标准的 HTTP JSON 轮询APP 端定时拉取新消息。要接入 APP先确认接口存在。常见做法是在项目里提供api/目录或mobile/接口文件。用 curl 直接测一下登录接口能不能通curl -X POST http://你的域名.com/api/login \ -H Content-Type: application/json \ -d {username:admin,password:admin123}接口路径每个版本不一样可能是api/login.php、api/agent_login或mobile/index.php?actionlogin。先用上面的命令试404 就在项目代码里搜function login或者login_action这类关键字。我的经验是 2021 年 12 月修复版一般会给出一个明确的api/目录接口的路径会在自带教程里列出来。如果教程没写用 grep 找grep -rn api --include*.php | grep -i login。4.2 登录鉴权接口对接token 设计与设备绑定APP 登录接口最重要的事情是拿到 token后续所有请求都带着这个 token。服务端那边的实现参考如下不要直接复制以你拿到的那版代码实际逻辑为准// api/agent_login.php —— 简化示例说明 token 机制 $json file_get_contents(php://input); $data json_decode($json, true); $username addslashes($data[username]); $password md5($data[password]); $sql SELECT id, name, role FROM users WHERE username{$username} AND password{$password} AND roleagent; $user $db-query($sql)-fetch(); if ($user) { // 用 user_id 时间戳 密钥 生成 token $token md5($user[id] . time() . your-secret-key); $db-query(UPDATE users SET app_token{$token}, last_login_timeFROM_UNIXTIME(.time().) WHERE id{$user[id]}); echo json_encode([code0, data[token$token, user$user]]); } else { echo json_encode([code1, msg用户名或密码错误]); }逻辑说明这个接口接收 APP 传来的用户名和密码先在数据库中查是否存在对应的坐席账号验证通过后生成一个 token存到数据库里同时返回给 APP。后续 APP 的所有请求都要带上 token服务端只需要查app_token字段是否匹配就能识别身份而不需要每次再传密码。参数说明里有几个点要留意md5用于密码加密是这套老系统的通行做法你能改就改成更强的哈希改不了至少保证 APP 端传输时用 HTTPSapp_token字段在有些版本里不存在需要你先ALTER TABLE users ADD COLUMN app_token VARCHAR(64)加一个字段token 有效期建议加上校验逻辑比如接口调用时检查last_login_time是否过了 X 天避免 token 永久有效导致安全隐患。APP 端拿到 token 后的调用逻辑用 curl 模拟一下curl -X POST http://你的域名.com/api/get_conversations \ -H Authorization: Bearer 上一步拿到的token \ -H Content-Type: application/json \ -d {page:1,page_size:20}这个接口如果返回了会话列表说明鉴权链路已通。如果返回 401检查 token 在服务端是否被正确读取——注意 PHP 里取 Header 的方式是$_SERVER[HTTP_AUTHORIZATION]有的环境需要在 Nginx 里加一句配置fastcgi_param HTTP_AUTHORIZATION $http_authorization;才能取到这条非常隐蔽卡住过很多人。4.3 消息收发与离线补推送轮询和多端同步的坑APP 端收消息最省事的方式是短轮询。比如每 5 秒请求一次/api/get_new_messages带上last_message_id让服务端从某条消息 ID 开始往后拉新消息// api/get_new_messages.php —— 简化示例 $token get_bearer_token(); $user get_user_by_token($token); $last_id intval($_GET[last_id]); // 约定消息表的自增ID越大越新 $sql SELECT m.*, u.name AS sender_name FROM messages m LEFT JOIN users u ON m.sender_id u.id WHERE m.to_agent_id {$user[id]} AND m.id {$last_id} ORDER BY m.id ASC; $messages $db-query($sql)-fetchAll(); echo json_encode([code0, data$messages]);逻辑说明APP 端本地维护一个last_id每轮拉取时传上去服务端只返回比这个 ID 大的消息。好处是断网期间积压的消息也能在联网后一次拉回来天然具备离线补数据能力。参数说明to_agent_id决定了坐席只能看到分给自己的会话这要求访客进线时的分配逻辑正确如果发现 APP 上只能看到部分会话去查分配逻辑里是不是把to_agent_id写成了0。轮询频率建议设在 5 到 8 秒之间。低于 5 秒服务器压力大高于 8 秒坐席回复时感觉有明显延迟。另外注意时区数据库里created_at如果存的是服务器本地时间APP 端显示消息时间时要么传给前端时间戳让手机本地格式化要么在后端统一转成UTC8否则就会出现「消息明明刚发排序却跑到了最下面」的怪问题这种问题排查起来很费劲大多数人第一反应是消息表数据错了实际上只是时间字段时区不一致。还有多端同步问题同一个坐席在 PC 后台和手机 APP 同时登录回复消息时可能产生冲突。常见做法是消息表里增加字段reply_by或者直接看sender_id来判断是谁回复的。如果那版代码没有这个字段建议加上索引否则会话记录多了之后查询会越来越慢。5. 部署和使用中的常见问题排查5.1 安装后网站白屏或 HTTP 500 错误现象访问站点首页或登录后台时一片空白没有报错信息Chrome 开发者工具看到 HTTP 500。原因最常见的是两个。一是 PHP 版本太高老代码触发了致命错误但display_errors没开错误信息被吞了二是项目目录权限不对PHP 进程无法读取文件或写缓存目录。解决先把错误显示打开在index.php头部加两行代码error_reporting(E_ALL); ini_set(display_errors, 1);然后刷新页面此时页面上大概率会直接显示错误信息。如果是Deprecated: Methods with the same name之类说明版本兼容问题如果是Permission denied执行chown -R www-data:www-data /var/www/kefu/。打开错误显示后务必在生产环境关闭这是常识。5.2 访客能发起对话但坐席后台收不到消息现象访客端聊天窗口显示已发送但坐席后台列表始终看不到新会话。访客端聊得热火朝天坐席端一片清净。原因一般是路由或伪静态配置问题。老系统的访客请求和坐席拉取消息用的是不同 URL如果 Nginx 只给其中一个装了 rewrite 规则另一个请求就会 404 或被指向错误的后端。另一个常见原因是 PHP 进程的 session 目录不可写导致会话数据写不进去。解决先看 Nginx 配置里是否包含location / { try_files $uri $uri/ /index.php?$query_string; }伪静态规则。如果你用的是 Apache确认.htaccess文件存在且AllowOverride All已开启。如果配置没问题再检查 session 目录chmod -R 777 /var/lib/php/sessions/。这些做完重启 PHP-FPM再测一次。还有一个玄学现象是防火墙或代理把消息拉取的轮询请求拦截了这个检查 Nginx access log 就能看出来。5.3 手机 APP 登录成功但拉不到会话列表现象APP 能登录能拿到 token但会话列表永远为空。PC 后台明明有会话APP 里就是看不到。原因APP 调用的是 API 接口API 接口查的可能是另一张表或者查询条件多了一个status过滤条件。比如 PC 后台显示的是全部状态的会话API 只查了status active状态的会话而访客的会话已经是closed状态。解决直接去数据库里看。在 MySQL 里执行查询看 API 查询语句查出来的数据是什么条件SELECT id, visitor_id, agent_id, status, created_at FROM conversations ORDER BY id DESC LIMIT 10;看到数据后去代码里找 API 对应的查询语句把过滤条件改宽。例如原来是WHERE agent_id $agent_id改成WHERE agent_id $agent_id OR status pending确保新会话也能被拉取。这类问题的排查思路就一条APP 拿不到数据先确认数据库里有数据再确认代码的查询条件没把数据过滤掉这个顺序别搞反。5.4 坐席上限改完重启后又被重置现象数据库或代码里改了坐席上限当时测试有效但过几天再登录后台发现坐席数又被限制住了。新增坐席时又提示超过上限。原因系统存在定时任务或某种「自修复」逻辑定期把配置表里的值重置回默认值。最常见的是 cron 脚本里写死了默认配置每次运行都会把数据库里的max_agents更新回 3。解决先查 crontabcrontab -l看看有没有定时执行 PHP 脚本的任务。如果有打开脚本看是否包含类似UPDATE settings SET setting_value3 WHERE setting_namemax_agents的语句。找到后把它注释掉或改成 999999。另外一个隐蔽来源是系统自带的后台「保存设置」功能如果后台开启了什么自动校准保存一次就覆盖一次这种情况直接在后台把设置项改成目标值保存就永久生效了。5.5 数据库连接数被轮询请求打满现象坐席在线数量稍微多一点数据库就开始报Too many connections整个系统卡死重启 MySQL 后好一会儿过阵子又卡死。原因老版本的消息拉取机制是每个坐席一个轮询请求每个请求直接连数据库。如果你用的 PHP-FPM 子进程数是 50每个子进程同时发起一个数据库连接而 MySQL 默认max_connections是 151生产环境很容易被打满。解决不要急着调 MySQL 的max_connections那只是治标。先看代码里是否用了持久连接mysql_pconnect或PDO::ATTR_PERSISTENT持久连接会长期占用 MySQL 连接数果断关掉再把轮询间隔从 3 秒调成 8 秒请求量直接降一半多。最后考虑引入一个简单的 Redis 缓存做消息队列把轮询的读压力从 MySQL 上卸掉——这个属于改造范围但这套系统的老版本架构不做改造就老实控制坐席在线数别贪多。6. 进阶用「会话追踪链路」验证系统是否真正健康系统跑通之后绝大多数问题都不会再出现在表面而是藏在深层次的链路里。我建议你做一个贯穿访客端、服务端、坐席端、APP 端的消息追踪测试这个比任何监控面板都更早暴露出隐患。在数据库里找到消息表通常是messages表然后模拟完整流程。用访客端发一条消息立刻去查数据库SELECT id, visitor_id, agent_id, sender_id, content, created_at FROM messages WHERE content 链路测试 ORDER BY id DESC LIMIT 5;这条 SQL 查出来的结果要满足三个条件id 是递增的、sender_id 正确区分了访客和坐席、created_at 是当前时间。然后坐席端回复一条再看记录重点确认agent_id是否被正确填上。如果 agent_id 是空或 0那这条回复在 APP 端极有可能不可见。接下来做 APP 端验证用测试账号在 APP 上登录发一条新访客消息看 APP 在 10 秒内能否收到。10 秒这个数字来自轮询间隔上限如果经常超过 10 秒说明轮询队列有积压或者 PHP 响应太慢用top看 PHP-FPM 的 CPU 占用再用journalctl -u php7.4-fpm --since 10 minutes ago看有没有慢请求日志。这个追踪链路我每次部署必做虽然耗时不到半小时但调试的次数越多越能体会它的价值——它能在问题影响到真实访客之前就暴露隐患。我个人的使用习惯是在医院或者出门路上遇到客户反馈消息没回坐席端只剩手机这个入口链路追踪能力直接决定我要不要开电脑。如果你只有一台服务器先把上面这些排查手段存好比收藏十个部署博客都管用。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑