0

Probably a silly quesiton about wp_query and if -> have posts etc.

I have new WP_Query ($taxonomy_query) and then I run an if while:

<?php if ($taxonomy_query->have_posts()) : while ( $taxonomy_query->have_posts() ) : $taxonomy_query->the_post();   ?>

That I then do stuff with and end with

<?php   endwhile;   endif;  wp_reset_postdata();?>

Then further down the page I use a foreach using:

<?php
     $tax_countries = $taxonomy_query->posts;
     foreach ($tax_countries as $option) {
      echo '<option value="'.$option->ID .'">'.$option->post_name .'</option>';
     }
     ?>

Is this a problem? Is there a more efficient way.

I was trying to create an array in the original if while above and then do a foreach on the array but thought it wasn't a good idea.

Any thoughts on this? Any help pointers would be most appreciated. Thanks, D.

4
  • Also it is ok to you multiple wp_queries on a single page?
    – user142553
    May 13, 2018 at 16:37
  • Why not just use have_posts for both loops? Why is the second a foreach on the posts? May 13, 2018 at 16:41
  • Hi Jacob - could you care to elaborate please as I'm not sure what you mean? Thanks.
    – user142553
    May 13, 2018 at 16:45
  • Why are you looping through the same query in two different ways? May 13, 2018 at 16:47

1 Answer 1

2

No, the problem lies in the parts you didn't put in your question, namely, the performance characteristics of a query are entirely down to this bit:

I have new WP_Query ($taxonomy_query) and then I run an if while:

That initial = new WP_Query([... is responsible for the entirety of the performance cost.

By the time the loop starts, the expensive part is already over. So no, your loop is fine, there is no room for optimisation here if you're looking for performance gains. It's what you're querying for that determines the cost.

Then further down the page I use a foreach using:

$tax_countries = $taxonomy_query->posts;
foreach ($tax_countries as $option) {

I consider this suboptimal, it would be better to use a standard post loop instead, combined with the rewind_posts method to put the loop back at the start.

You also didn't call have_posts on your query.

So, you should be able to do the following to run the same loop twice:

$q = new WP_Query([... arguments go here ...]);
if ( $q->have_posts() ) {
    while ( $q->have_posts() ) {
        $q->the_post();
        // do stuff
    }
    $q->rewind_posts();
    while ( $q->have_posts() ) {
        $q->the_post();
        // do other stuff
    }
    wp_reset_postdata();
} else {
    // nothing found
}

Nitpicking

  • Do 1 thing per line, don't pile in all your if and while opening and closing clauses on the same line, it's counterproductive and makes stuff harder to read
  • Stick to a standard post loop and WP_Query as much as possible, aint nobody got time for 4 or 5 functions that all call WP_Query anyway, with all their edge cases and caveats
  • Use { } syntax, it works much better with editors and automated tools, let your editor do all the heavy lifting ( which it can't do if you use endwhile; etc )
  • If no posts were found, it still calls wp_reset_postdata even though there is no post data to reset! Put this after the loop but inside the if statement.
  • Use tabs to indent as the WP coding standards dictate, and let your editor indent for you. If you must use spaces, pick a coding standard and stick to it, but most importantly, be consistent. Again any half decent editor will do this for you
  • If you're replacing the main query, instead of doing an extra query, use pre_get_posts instead
4
  • 1
    Thank you very much for your response - I do really appreciate it.
    – user142553
    May 18, 2018 at 6:28
  • @user142553 I added a generic example, if this answers your question consider marking it as correct by clicking the tick under the vote counter :)
    – Tom J Nowell
    May 18, 2018 at 12:13
  • I like @TomJNowell answer. I want to say this is pretty standard rules, but someone doesn't follow and make our life harder. haha.
    – idpokute
    May 18, 2018 at 13:36
  • 1
    Brilliant - thanks for doing that - it really made it much clearer for me. I appreciate the time.
    – user142553
    May 22, 2018 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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