get_posts() is a nice little function and is widely used within themes and plugins, but what most people don’t keep in mind is that there is at least one database query behind each of the calls. With taxonomy,category or meta queries it’s even more, so caching the result of this function can have quite an performance impact.
Here is my approach:
/** * Wrapper around get_posts that utilizes object caching * * @access public * @param mixed $args (default: NUL) * @param bool $force_refresh (default: false) * @return void */ function get_posts_cached( $args = NULL, $force_refresh = false ) { $cache_incrementor = wp_cache_get( 'get_posts_cached', 'cache_incrementors' ); if ( !is_numeric( $cache_incrementor ) || true === $force_refresh ) { $now = time(); wp_cache_set( 'get_posts_cached', $now, 'cache_incrementors' ); $cache_incrementor = $now; } $cache_key = 'get_posts_cached_' . $cache_incrementor . '_' . md5( serialize( $args ) ); $cache_group = 'get_posts_cached'; $posts = wp_cache_get( $cache_key, $cache_group ); if ( false === $posts || true === $force_refresh ) { $posts = get_posts( $args ); if ( count( $posts ) < 11 ) // we don't want to cache too much wp_cache_set( $cache_key, $posts, $cache_group ); } return $posts; } /** * Invalidate get_posts_cached stored values. * * @access public * @return void */ function invalidate_get_posts_cache( $post_id ) { $args = array( 'include' => array( $post_id ) ); get_posts_cached( $args, $force_refresh=true ); } add_action( 'save_post', 'invalidate_get_posts_cache', 1 );
As you can see this is mainly a wrapper around get_posts() but it adds some magic. It utilizes the object cache to store the results of the get_posts() call. If there is already a valid cache object it will return this, if not it will rebuild the cache from the db by calling get_posts().
As you can see there is no timeout on the object. We simply enforce a refresh of all objects each time a post is saved. This can be done by adding a counter ($cache_incrementor
) to the cache key. Once we want to invalidate all cache objects in the group we simply increment this counter. Kudos for this method goes to advanced-caching
If you don’t have an object cache you could also replace the wp_cache_get and wp_cache_set functions with their get_transient and set_transient counter-parts.
Trackbacks/Pingbacks
[…] and wp_cache_set features with their get_transient and set_transient counter-parts.script by : THORSTEN.ads-block ul li span{font:15px […]