Are transients private or public?

Are WP transients specific to the user-session or can they be accessed from any session anywhere?

Since they are written to the DB, I would imagine they are public and accessible everywhere, but is there a way to limit their scope to only one user’s session?

Read More

The website I am building does not offer a login/memmbership option. By user I mean anyone that is viewing the website – I’m not talking about wp_users!

Example:

  • I load the home page which generates a random number and stores it into a transient which should be accessible within that same session.

  • However, even from the same computer, but from a different browser, or different IP, I should not be able to access this transient…

Is this possible?

Related posts

2 comments

  1. Transients are just database keys that expire. It’s like telling WordPress you want it to remember a certain piece of information, but for a limited time. In general, transients are accessible to PHP through any request.

    But since they’re server-side, transients are only exposed to front-end users if you as the developer expose them.

    A Solution

    Given your specific question:

    I load the home page which generates a random number and stores it into a transient which should be accessible within that same session.

    I would recommend pairing Transients with cookies. Basically, generate a unique key for every request (perhaps a hash of time() and some randome number) and use that as the user’s session key. Then, you can store a transient for just that user. Be sure to pass this unique key to the browser in the way of a cookie, and the next time that same user refreshes the page, they’ll get the same number.

    To give you some untested pseudo-code …

    /**
     * Check the user's cookie if they have it.
     * Create one if they don't.
     */
    function wpa_105249_check_cookie() {
        if ( isset( $_COOKIE['wpa_105249_key'] ) ) {
            $key = (string) $_COOKIE['wpa_105249_key'];
        } else {
            $key = md5( time() . rand() );
    
            // Set the browser cookie to expire in 30 minutes
            set_cookie( 'wpa_105249_key', $key, time() + 30 * 60 )
        }
    
        // Try to grab the transient from the database, if it exists.
        $transient = get_transient( 'wpa_105249_' . $key );
    
        // If the transient doesn't exist, create it.
        if ( false === $transient ) {
            // Call your function to generate the random number.
            $transient = generate_random_number();
    
            // Store the transient, but expire in 30 minutes.
            set_transient( 'wpa_105249_' . $key, $transient, 30 * 60 );
        }
    
        wp_cache_set( 'wpa_105249_number', $transient );
    }
    add_action( 'plugins_loaded', 'wpa_105249_check_cookie' );
    

    In plain English, this will:

    1. Check for the wpa_105249_key cookie in the request
      • If the cookie doesn’t exist, create one.
      • Set the cookie in the page’s response headers so the browser has it for next time.
    2. Attempt to grab a transient as identified by the cookie
      • If the transient doesn’t exist, generate a new random number using your function and store it in the transient for next time.
    3. Set the random number in the request cache

    Any code you call after this – basically anywhere else in your code – you can grab the current user’s random number simply by calling:

    $number = wp_cache_get( 'wpa_105249_number' );
    
  2. Transients are persistent storage mechanism. That means that by saving transient with certain key you will be able able to retrieve same transient with that same key (if it had not expired and cache have not been flushed since).

    “Public” does not really apply to them, since they are internal code concept and only thing that accesses them is your code, not user’s browser.

    If you want to store user-specific data in transient it will probably be challenging to come up with user-specific keys for it.

    Storing information in user’s cookies or using some kind of proper session mechanism will probably be a better fit.

Comments are closed.