php 8.5 不支持原生 websocket 服务,需依赖 workerman 等第三方库实现;workerman 启动需三步:安装、启用 pcntl/posix 扩展、实例化 worker 并设置 name/count 属性。

PHP 8.5 不支持原生 WebSocket 服务
PHP 本身没有内置 WebSocket 服务器能力,PHP 8.5 也不例外——它只是语言版本升级,不新增网络服务框架。所谓“PHP 实现 WebSocket”,实际是靠扩展或第三方库在 PHP 进程里模拟 TCP 长连接处理逻辑。你不能直接用 fsockopen 或 Swoole\Http\Server(如果没装 Swoole)就跑起一个生产级 WebSocket 服务。
Workerman 是目前最主流的纯 PHP 实现方案,不依赖 Swoole,兼容 PHP 7.4–8.5,靠 stream_socket_server + 轮询/事件循环工作。
Workerman 启动 WebSocket 服务的关键三步
Workerman 的 Websocket\Server 类封装了握手、帧解析和心跳,但必须手动绑定回调、启动监听,且不能和 Apache/Nginx 共用端口(它自己就是服务器)。
- 确保已用
composer require workerman/workerman安装,且 PHP 启用了pcntl和posix扩展(Windows 下需改用php start.php start -d的非守护模式) - 入口文件(如
ws.php)中必须实例化Workerman\Worker并设置$worker->name和$worker->count,否则多进程会异常 - WebSocket 协议校验由 Workerman 自动完成,但
onMessage回调收到的是解包后的字符串/数组,不是原始帧;若前端发的是 JSON,这里直接json_decode($data, true)即可,不用再 base64 或 unpack
<?php
use Workerman\Worker;
use Workerman\WebSocket\Connection;
require_once 'vendor/autoload.php';
$ws_worker = new Worker('websocket://0.0.0.0:2346');
$ws_worker->onMessage = function(Connection $connection, $data) {
$connection->send('echo: ' . $data);
};
Worker::runAll();
常见连接失败:端口、跨域、SSL 三处卡点
浏览器连不上 ws://localhost:2346,90% 是这三个原因:
立即学习“PHP免费学习笔记(深入)”;
- 端口被占用或防火墙拦截:
lsof -i :2346(macOS/Linux)或netstat -ano | findstr :2346(Windows)确认端口空闲;云服务器还要检查安全组是否放行该端口 - 前端 JS 显式指定协议时写错:
new WebSocket('ws://...')不能写成http://;HTTPS 页面强制要求wss://,否则浏览器直接拒绝连接(不是报错,是静默失败) - Workerman 默认不处理 HTTPS/WSS:
wss://必须配合 Nginx 反向代理,或自行加载 SSL 上下文(需ssl://协议 +context参数传入证书路径),否则客户端会卡在 TLS 握手
PHP 8.5 下 Workerman 的兼容性注意点
Workerman 4.1+ 已适配 PHP 8.5,但有些旧项目迁移时容易忽略:
- 废弃的
each()函数已被彻底移除,若你 fork 的 Workerman 分支或自定义组件里还用它,会直接 fatal error;搜each(替换为foreach - Workerman 的
Connection对象在 PHP 8.5 中对属性访问更严格,$connection->uid = 123可以,但$connection->undefined_prop会触发Warning: Undefined property(PHP 8.2+ 默认开启严格模式) - 调试时别依赖
var_dump($connection)——它会递归打印整个连接上下文,极易内存溢出;改用var_export($connection->getRemoteIp(), true)这类轻量方法
真正难的不是启动服务,而是连接稳定后怎么管理用户状态、广播消息、应对断线重连。Workerman 没有内置 session 或房间管理,这些得你自己用 $_SESSION(不推荐)、Redis 或全局数组存,稍不注意就内存泄漏。











