azjezz/psl
PSL is a modern, well-typed standard library for PHP 8.4+, inspired by HHVM’s HSL. It offers safer, predictable APIs for async, collections, networking, I/O, crypto, terminal UI, and robust data validation—replacing brittle built-ins with consistent alternatives.
The H2 component implements the HTTP/2 binary framing protocol (RFC 9113) on top of PSL's IO handles. It is a building block for higher-level components like HTTP clients and servers, not an HTTP implementation itself. The protocol is implemented in full - if the RFC defines it, H2 supports it.
H2 connections take a Psl\IO\ReadHandleInterface & Psl\IO\WriteHandleInterface instance. That could be a TCP stream, a TLS connection, a Unix socket, or anything else that implements those interfaces. H2 does not care about the transport.
PSL's IO and Async components are built on top of Revolt. H2 is concurrent by design: operations like waitForSendWindow() suspend the current fiber and let the event loop run until a WINDOW_UPDATE arrives. Multiple streams on the same connection run in parallel through fibers.
To use H2 with other event loop libraries like ReactPHP, use revoltphp/event-loop-adapter-react and wrap your stream in a class implementing ReadHandleInterface & WriteHandleInterface.
Connections are split into ClientConnection and ServerConnection, each implementing their role-specific interface. Both share common operations (sending headers, data, ping, goaway) via ConnectionInterface.
@example('protocols/h2-client-server.php')
sendData() sends a single frame and requires the caller to manage flow control windows. For large payloads, use sendAllData() which automatically splits data into window-sized chunks and waits for WINDOW_UPDATE frames.
@example('protocols/h2-flow-control.php')
Server push is part of the HTTP/2 specification, so H2 implements it. Whether higher-level code chooses to use it is an application-level decision. sendPushPromise() sends pushes, rejectPush() declines them.
@example('protocols/h2-server-push.php')
RFC 8441 enables protocols like WebSocket to run over HTTP/2 streams. The client sends an extended CONNECT request with a :protocol pseudo-header, and after the server responds with 200, the stream becomes a bidirectional byte tunnel.
@example('protocols/h2-extended-connect.php')
Servers can advertise alternative service endpoints (RFC 7838) for protocol migration, and declare authoritative origins (RFC 8336) for connection coalescing.
@example('protocols/h2-altsvc-origin.php')
The unified Configuration class replaces the deprecated ServerConfiguration and ClientConfiguration. It provides immutable builder patterns with with* methods and supports BDP auto-tuning for both client and server connections. When maxReceiveWindowSize is set, the connection dynamically sizes its receive window based on measured throughput and RTT using PING round-trips. Both ClientConnection and ServerConnection accept the new Configuration alongside their legacy types for backwards compatibility.
Beyond the core 10 frame types, the component supports:
Unknown frame types are silently ignored per the RFC, ensuring forward compatibility.
See src/Psl/H2/ for the full API.
How can I help you explore Laravel packages today?