PHP无法直接连接浏览器发起的wss:// WebSocket,因其不参与前端握手且脚本执行完即退出;正确方式是PHP作为客户端连第三方服务,或作为常驻服务端实现WebSocket协议。

不能直接用 PHP 原生 socket 连接浏览器端的 wss:// 页面所发起的 WebSocket 连接——因为 PHP 不是运行在浏览器里,它压根不参与前端 WebSocket 的握手和通信。
PHP 本身不是 WebSocket 客户端(浏览器才是)
当你在 HTTPS 页面里用 JavaScript 写 new WebSocket('wss://example.com/ws'),这个连接是由浏览器发起并维持的。PHP 脚本此时早已执行完、响应返回、进程退出。它无法“接入”这个已建立的浏览器 WebSocket 连接。
- PHP 没有
WebSocket对象,也不支持onmessage/onopen这类事件回调 - 所谓“PHP 连 WebSocket”,实际只有两种合法场景:PHP 作为独立客户端连第三方 WebSocket 服务(如行情推送),或作为服务端实现 WebSocket 协议(需常驻进程)
- 如果你的目标是“让 PHP 后端和前端页面共享实时数据”,那本质是需要一个 WebSocket 服务端(如
ReactPHP、Swoole、Workerman),再由前端 JS 连它,PHP 后端通过 TCP/IPC/HTTP 等方式与该服务端交互
混合协议下常见的误配点:ws:// vs wss:// + HTTPS 页面
现代浏览器强制要求:HTTPS 页面中,WebSocket 构造函数只能接受 wss://(加密)地址,拒绝 ws://(明文)。否则会直接报错:
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://example.com/ws'. This request has been blocked.
- 前端必须用
wss://,且证书需有效(自签名证书会被浏览器拦截,除非用户手动信任) - 后端 WebSocket 服务(如 Swoole 启动的
wssserver)必须配置 TLS,即传入ssl_cert_file和ssl_key_file,不能只开ws端口再套 Nginx 反代了事——Nginx 反代wss需要额外配置proxy_pass https://...并透传 Upgrade 头,实操极易漏掉proxy_set_header Upgrade $http_upgrade;等关键项 - 若用 Nginx 做
wss终结,PHP-FPM 仍只是普通 HTTP 后端,和 WebSocket 无任何直接连接关系
PHP 主动连外部 WebSocket 服务(如推送 API)可行但受限
PHP 可以用 stream_socket_client() 或 fsockopen() 手动实现 WebSocket 握手,但极不推荐:协议细节多(Sec-WebSocket-Key 计算、base64、SHA1)、无帧解析、不支持 ping/pong、难以维持长连接。
立即学习“PHP免费学习笔记(深入)”;
- 更现实的做法是使用成熟库,如
textalk/websocket(同步阻塞)或amphp/websocket(协程异步) - 注意:PHP CLI 模式才能长期运行 WebSocket 客户端;Web SAPI(如 Apache mod_php)每次请求结束就断开,无法维持连接
- 若目标服务只提供
wss,PHP 客户端需确保 OpenSSL 支持,并在stream_context_create()中启用'ssl' => ['verify_peer' => true](生产环境别关校验)
真正卡住多数人的不是“能不能连”,而是混淆了「谁在建连」「谁持有 socket」「谁负责心跳和重连」。浏览器 WebSocket 是单向隔离的,PHP 想掺和进去,必须绕到服务端中间层,而不是幻想用 file_get_contents() 或 cURL 去“调用”一个 wss:// 地址——那根本不是 HTTP 接口。











