PHP 8.5 不支持原生 WebSocket 服务,需依赖 Workerman 等扩展;使用时须满足:Workerman 4.1.0+、禁用 CLI 模式 Opcache、用 -d 后台启动,并注意端口暴露与进程管理。
PHP 8.5 本身不支持 WebSocket 服务
PHP 8.5 是语言核心,它没有内置 WebSocket 服务器能力,也没有
扩展。你看到的“PHP WebSocket”几乎全是靠外部库或框架模拟/桥接实现的,不是 PHP 自己在 listen 和 upgrade。
常见误解是以为升级到 PHP 8.5 就能直接写
——根本不存在这个类,也永远不会有。
PHP 官方明确不计划加入原生 WebSocket 服务支持(只保留客户端基础如
+ 手动协议处理)
和
都是独立扩展,和 PHP 版本号无强绑定,但需注意兼容性声明
PHP 8.5 对协程、类型系统等有增强,但没改变 I/O 模型——还是阻塞式默认,得靠扩展破局
Workerman 在 PHP 8.5 下跑 WebSocket 的真实条件
Workerman 不依赖 PHP 协程,靠多进程 +
/
实现异步,所以 PHP 8.5 完全可用,但要注意几个硬性前提:
必须用 Workerman 4.1.0+(旧版对 PHP 8.3+ 的 strict type 和反射变更兼容差)
不能开
(Workerman 启动时动态加载类,Opcache 会缓存失败)
WebSocket 协议解析由 Workerman 内置完成,你只需处理
、
等回调,不用碰
或帧掩码
启动命令必须用
,不能直接
(前台运行会阻塞,且信号处理异常)
最小可运行示例(
):
立即学习
“
PHP免费学习笔记(深入)
”;
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
为什么别用 PHP 写 WebSocket 握手和帧解析
手动实现 WebSocket 协议(RFC 6455)在 PHP 里非常脆弱,尤其在 PHP 8.5 的严格类型和错误报告下,容易触发以下问题:
:HTTP header 解析不规范,大小写敏感或代理改写导致
:WebSocket 帧解析时二进制长度计算错位,PHP 8.5 对
格式校验更严
连接卡在
状态:没正确响应 101 Switching Protocols,或返回头缺失
文本帧被截断或乱码:没处理好 UTF-8 多字节边界,PHP 8.5 的
函数默认行为更保守
Workerman、Swoole 这些方案的价值,就是把这部分脏活封死在 C 扩展或高性能 PHP 层里,你只管业务逻辑。
PHP 8.5 + Workerman 部署时最常漏掉的三件事
本地跑通不等于线上可用,尤其在 Docker 或 systemd 环境下:
没暴露容器端口:
忘加,或防火墙没开
(不是 80/443)
没设
导致
失效——Workerman 找不到旧进程 PID
用
管理时,没设
和
(Workerman 启动快,startsecs 默认 1 秒会误判失败)
检查是否真在监听:
,看到
进程才靠谱;只看到
但没进程名,大概率是启动命令没加
或报错了静默退出。
ext-websocketnew WebSocketServer()fsockopenext-swooleext-workermanselectepollopcache.enable_cli=1onMessageonConnectSec-WebSocket-Keyphp start.php start -dphp start.phpstart.phpuse Workerman\Worker;
use Workerman\Lib\Timer;
require_once 'vendor/autoload.php';
$ws_worker = new Worker('websocket://0.0.0.0:2346');
$ws_worker->count = 4;
$ws_worker->onMessage = function ($connection, $data) {
$connection->send('echo: ' . $data);
};
Worker::runAll();Undefined array key "Sec-WebSocket-Key"Uncaught ValueError: unpack(): Argument #2 ($format) must be a valid format stringunpack()openingConnection: Upgrademb_docker run -p 2346:23462346worker->name./start.php restartsupervisorautorestart=truestartsecs=0ss -tlnp | grep ':2346'phpLISTEN-d