6

I'm running the following PHP Code Sniffs on some WordPress code, and the following warning pops up

 352 | WARNING | get_posts is discouraged in favor of creating a new
     |         | WP_Query() so that Advanced Post Cache will cache
     |         | the query, unless you explicitly supply
     |         | suppress_filters => false.

While I'm an experienced programmer, I'm not super familiar with WordPress's history. This warning seems important, but is awkwardly worded. I'm confused on a few points, and other answers I've found on the subject don't seem to address my points.

  1. What is the "Advanced Post Cache". I know WordPress (like a lot of PHP applications) has caching going on at a few different levels.

  2. Is this warning telling me that get_posts will never use the cache, but WP_Query will?

  3. Is this warning telling me that using suppress_filters with WP_Query will bypass the Advanced Post Cache? Or that using suppress_filters with get_posts will invoke the cache? Or something else?

  4. What else does suppress_filters do?

If someone more familiar with the matter could clue in a WordPress newb I'd appreciate it. I'm not looking for a "always use X, or never use Y" sort of answer -- I'm trying to understand the tradeoffs of each approach.

2
  • 1
    I would recommend always using WP_Query, it's what get_posts uses internally. Also as an aside, never use query_posts under any circumstances, and always remember to cleanup with wp_reset_postdata
    – Tom J Nowell
    Commented Aug 18, 2016 at 1:53
  • if I've answered your question don't forget you can mark it as correct, or comment on it if it didn't
    – Tom J Nowell
    Commented Aug 21, 2016 at 18:20

1 Answer 1

10

Edit: WP Core has changed since the question and answer were written. While I still believe it's better to use WP_Query for other reasons, the suppress_filters rule should be gone from WPCS/VIPCS now

See https://github.com/WordPress/WordPress-Coding-Standards/issues/1416#issuecomment-1311724183 for why

As for which you should use, use WP_Query directly. get_posts uses it internally, and running the post loop fires lifecycle hooks that don't happen when you use get_posts with a foreach loop. You're also forcing WP to return an array of full posts, increasing memory footprint and eliminating opportunities to lazyload.


Parts of Original Answer:

WP_Cache

The original concern behind the sniff was that get_posts suppressed the use of WP Cache, which is no longer the case. Hence why the sniff mentions advanced cache.

Normally when WP fetches a post, it stores it in WP_Cache along with all its terms and post meta. This is why repeatedly calling get_post_meta doesn't repeatedly query the database.

This is why a common mistake in new WP developers is to try and create variable caches to avoid database queries, WordPress already does this. Unfortunately these variable based caches do not live beyond that page request and are empty on the next request as a result.

Persistent WP_Cache object-cache.php and advanced-cache.php

However, there are plugins and drop in files that provide advanced-cache.php or object-cache.php, which can make WP_Cachebe made persistent. This is usually done by storing the data in software such as Redis/Memcached or another 3rd party data store that runs in the background in memory.

For example, batcache will make WP_Cache use memcached to store things, letting data persist between page loads, improving performance significantly. There are similar plugins for Redis/memcache/etc, and they can give HUGE performance gains.

Enabling a persistent object cache with dedicated software can give massive performance benefits that rival the biggest hardware even when used on the tiniest of servers, often times eliminating most if not all database queries.

Note that this is different from caching things in files/folders.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.