Swoole Buffer 不是替代 PHP 字符串的通用工具,而是专为 TCP 粘包、协议帧构造、二进制流暂存设计的底层内存结构;适用于数据不完整接收、精确字节操作及高并发私有缓存场景,而非字符串拼接。
直接说结论:Swoole Buffer 不是拿来替代 PHP 字符串的通用工具,而是专为 TCP 粘包、协议帧构造、二进制流暂存设计的底层内存操作结构;用错场景(比如拼接 JSON 响应)反而引入额外开销和维护成本。
它解决的是「数据不完整」和「协议控制权」问题,不是「字符串拼得快不快」问题。
recv() 可能只读到半个包,需要暂存等待后续数据 —— 这时用 $buffer->append() 累积,比字符串拼接更省内存、避免重复复制$buffer->write() 和 $buffer->read() 支持指针式操作,PHP 字符串做不到Buffer 实例做私有缓存,配合 clear() 复用内存,比每次 new string 更可控差异不在“快慢”,而在“是否触发内存重分配”。PHP 字符串是 copy-on-write,频繁 .= 会不断 realloc 内存;Buffer 底层是预分配可扩展内存块,append() 在容量内是 O(1) 操作。
Buffer 反而多一层对象封装开销Buffer 开始显现出优势,实测吞吐提升约 12%~18%$buffer->__toString() 会触发一次内存拷贝,不要在 hot path 频繁调用这是高频踩坑点。有人试图用 Buffer 接收 LLM token 流再统一 push(),结果卡住或乱序 —— 因为 Buffer 是纯内存容器,不带发送语义,也不参与 Swoole 的协程调度。
$server->push()(WebSocket)或 $response->write() + $response->flush()(HTTP),它们才真正对接 TCP 层Buffer 只适合“收”和“构”,不适合“发”;想攒 token 再发,应该用 CoChannel 或数组暂存,而不是靠 Buffer 缓冲Buffer 做中转,记得每次 push() 后调 $buffer->clear(),否则下次 append() 会叠在旧数据后面真正容易被忽略的是生命周期管理:Buffer 实例一旦创建就常驻内存,如果在 onMessage 里每次都 new SwooleBuffer() 却不 unset,Worker 进程内存会缓慢上涨;更稳妥的做法是在连接建立时初始化一次,挂到 $server->connections[$fd]['buffer'] 上,onClose 时调 $buffer->destroy()。