Every new TLS connection starts with a handshake, the exchange where the client and server agree on keys, and it takes time. Session resumption lets a client reuse what it learned from an earlier connection and skip most of that work. This RFC from Jakub Zelenka gives PHP streams full control over TLS sessions.
Why change it#
PHP could already copy a session from one open stream to another. What you couldn't do was:
- Save a client session and reuse it in a later PHP request.
- Store server sessions in your own backend, like Redis or a database.
- Control the server's built-in session cache.
Show me#
Here's a client that saves its session and reuses it next time:
$previousSession = $_SESSION['tls_session'] ?? null;
$context = stream_context_create([
'ssl' => [
'peer_name' => 'api.example.com',
'session_data' => $previousSession
? OpenSSLSession::import($previousSession)
: null,
'session_new_cb' => function ($stream, OpenSSLSession $session) {
$_SESSION['tls_session'] = $session->export();
},
],
]);
$fp = stream_socket_client('tls://api.example.com:443', context: $context);
session_new_cb runs when a new session is established, and session_data passes an earlier session back in so the connection can resume it.
What the RFC adds#
- A session class. It wraps a single TLS session. You can
export() it as PEM text or DER binary, import() it back, or use serialize(). It also exposes details like the protocol, the cipher and when the session was created. You can't create one with new.
- An exception class for the OpenSSL extension, thrown when a session can't be imported, exported or unserialized.
- Client options:
session_data and session_new_cb.
- Server options:
session_cache, session_cache_size, session_timeout and session_id_context configure the built-in cache. session_get_cb and session_remove_cb let you keep sessions in your own storage. num_tickets and no_ticket control session tickets, the other resumption mechanism in TLS 1.3.
Invalid options throw a TypeError or ValueError. An expired session triggers a warning, and PHP falls back to a full handshake.
What it means for existing code#
Nothing breaks, since all the new options are opt-in. The RFC names HTTP clients like Guzzle and Symfony HttpClient, and async tools like ReactPHP, Amp and Swoole, as likely users.