PHP不原生支持WebSocket客户端,因缺乏异步I/O和事件循环,需依赖第三方库(如textalk/websocket)或绕道方案(如调用Node.js客户端、REST接口转发),且仅适用于CLI模式,不适用于高并发Web环境。

PHP 本身不原生支持 WebSocket 客户端(即不能像 JavaScript 那样用 new WebSocket() 直接连接并收发消息),它没有内置的异步 I/O 和长连接事件循环,所以「PHP 连接 WebSocket 并发消息」这件事,必须借助第三方库或绕道方案——直接用 fsockopen 或 stream_socket_client 手动实现 WebSocket 握手和帧解析,极其复杂且易出错;实际项目中几乎没人这么干。
为什么不能直接用 curl 或 file_get_contents 发送 WebSocket 消息
WebSocket 是基于 TCP 的全双工协议,需要完成 HTTP 升级握手(Upgrade: websocket)、生成/校验 Sec-WebSocket-Key、处理掩码(masking)、按帧(frame)编码数据。而 curl 和 file_get_contents 只能发一次 HTTP 请求,无法维持连接、无法接收服务端推送、无法构造合法 WebSocket 帧——它们连握手都通不过,更别说后续通信。
推荐方案:用 Ratchet(PHP WebSocket 库)做服务端,但客户端换语言
如果你的目标是「从 PHP 后端向某个 WebSocket 服务(如聊天服务器)发一条消息」,正确做法不是让 PHP 当客户端,而是:
- 让 Node.js / Python / Go 写一个轻量 WebSocket 客户端(几行代码就能发消息),PHP 通过
exec、shell_exec或 HTTP API 调用它 - 或改用「HTTP 回调 + 消息代理」:WebSocket 服务暴露一个 REST 接口(如
/api/push),PHP 用curlPOST 数据过去,服务端内部转发到对应 WebSocket 连接 - 若你用的是 Ratchet 或 Workerman 作为 WebSocket 服务端,它通常自带管理接口或提供
push()方法,PHP 可通过 Redis 或 Socket IPC 通知服务端主动推消息
极少数必须 PHP 当 WebSocket 客户端的场景(如调试、CLI 工具)
这时只能用成熟封装库,例如 textalk/websocket(Composer 包):
立即学习“PHP免费学习笔记(深入)”;
composer require textalk/websocket
使用示例:
$client = new WebSocketClient("ws://localhost:8080");
$client->send('{"type":"msg","content":"hello"}');
$response = $client->receive();
注意点:
- 该库底层仍依赖阻塞 socket,不适用于高并发 Web 请求上下文(会卡住整个 PHP 进程)
- PHP-FPM 或 Apache 下运行会超时或被 kill,只适合 CLI 模式(
php script.php) - 不支持 wss(TLS)除非系统已安装 OpenSSL 且 PHP 编译时启用,连接时写
wss://即可 - 收到的消息是原始字符串,需自行
json_decode,发送前也需确保是 UTF-8 字符串
真正要让 PHP「参与」WebSocket 通信链路,重点不在“怎么连”,而在“谁该承担客户端角色”——多数情况下,PHP 守好自己的 HTTP/API 边界,把实时通信交给更合适的工具,反而更稳、更易维护。











