Why favour the standard WP loop over iterating over (new WP_Query())->get_posts()?

The WP loop goes like this:

if ( have_posts() ) {
  while ( have_posts() ) {
    the_post();
    ...

Why is it preferred over the following?

foreach( (new WP_Query())->get_posts() as $post ) { ... }

To me, it’s more apparent what is going on in the latter. I’m new to PHP and WP and I’m trying to understand why I should be using the former.

What do I gain by using the standard loop? Is iterating over get_posts() any less efficient?

2 Answers
2

Several reasons

1. Filters and Actions

By using the standard loop, you execute various filters and actions that plugins rely on.

Additionally, you set up the_post correctly, allowing functions such as the_content etc to work correctly. Some filters can even insert “posts” into the loop

2. Memory Efficiency

By fetching all the posts as an array, you’re forcing WP_Query to take the data it has and create WP_Post objects. With a standard post loop these are created as they’re needed

3. PHP Warnings

Your loop doesn’t check if any posts were actually found, so it’s impossible to give a “No posts available” style message. It’ll also generate PHP warnings at times.

4. Overriding WP globals

By using $post you’re overriding a global variable, which can have unintended consequences, especially if this loop is nested inside another loop you’re unaware of

5. PHP Efficiency and Correctness

Creating an object inside a foreach condition is bad practice, as is creating and then using an object without error checking.

6. Debugging

A lot of tools and plugins assume you’re using a standard loop and have been built to make life easier. By doing this you’re throwing all of that away

7. There are Better Alternatives

array_walk

A crude but superior option to your foreach might actually be array_walk:

$q = new WP_Query([ ..args ]);
array_walk( $q->get_posts(), function( $post ) {
    //
});

Note that I don’t recommend using array_walk.

PHP Generators

Now that’s not to say you couldn’t use a different style loop while still having all the advantages.

For example WP Scholar has an article showing a php generator based loop:

if ( have_posts() ) {
   foreach ( wp_loop() as $post ) {
      echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
   }
} else {
   echo '<h1>No posts found!</h1>';
}

This has the advantage that it still calls all the functions of a standard loop, but they’ve been abstracted away.

Creating a Better WordPress Loop

I’m sure there are others, but a standard loop is reliable predictable and readable to all

Leave a Comment