Skip to content
PHP News
Search
Implemented PHP 8.6

TLS Session Resumption Support for Streams

Adds a TLS session class and stream context options so clients and servers can save, store and resume TLS sessions.

Add TLS session resumption support to streams as described in this RFC?

Primary vote · 2/3 majority

19 Yes 0 No 3 abstain 100% approval

This poll has closed.

What should the exception class be named?

· 1/2 majority

  • Abstain 0
  • OpenSSLException (consistent with existing OpenSSL classes) 5
  • Openssl\OpensslException (namespaced per Throwable policy recommendation) 15

This poll has closed.

What should the session class be named?

· 1/2 majority

  • Abstain 1
  • OpenSSLSession (consistent with existing OpenSSL classes) 7
  • Openssl\Session (namespaced per latest naming conventions) 13

This poll has closed.

The main vote passed 19 to 0, with 3 abstaining, clearing the two-thirds majority it needed. Voting closed on April 8, 2026.

Two simple-majority votes chose the class names. The exception class will be Openssl\OpensslException, which won 15 to 5, and the session class will be Openssl\Session, which won 13 to 7 with 1 abstaining. The RFC's examples still use the older names, OpenSSLSession and OpenSSLException.

Summary

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.