Keeping Objects in Memory

This is a perfect use case for Transients.

In WordPress, transients are short-lived data objects. By default, they’re persisted to the database using WordPress’ built-in WP_Object_Cache object. However, you can use a variety of caching plugins (Batcache is an outstanding one that works with Memcached) to store Transients in memory.

To set a transient, call set_transient( 'a unique name', 'the data value', 'time in seconds until it disappears' );

Your situation is working with a project object. Here’s what you’d do:

function get_project( $user_id ) {
    if ( ! $project = get_transient( 'project_' . $user_id ) ) {
        // get_transient() returns false if the value is expired or doesn't exist.
        $project = new Project( $user_id );

        // Set the transient so that it lives for an hour
        set_transient( 'project_' . $user_id, $project, 3600 );
    }

    return $project;
}

Then, in your code, you can call get_project() whenever you need to reference the current project. If it exists in the cache, you’ll use the cached version. If it doesn’t, you can build a new instance and save it to the cache. There’s a lot more you’ll need to do if you want to manipulate the object after you’ve retrieved it (and have those manipulations persist in the cache), but that’s an exercise I leave to you.