Est-il nécessaire d'utiliser wp_reset_query () dans un appel WP_Query?

26

J'utilise le code suivant pour récupérer des messages:

<?php
$featuredPosts = new WP_Query();
$featuredPosts->query('showposts=5&cat=3');

while ($featuredPosts->have_posts()) : $featuredPosts->the_post(); ?>

    <h1><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h1>
    <div class="meta">
        By <?php the_author() ?>
    </div>
    <div class="storycontent">
        <?php the_excerpt(); ?>
    </div>

<?php endwhile; ?>

Dois-je utiliser wp_reset_query()? Si je le fais, où dois-je le placer?

janoChen
la source
2
Si vous comptez sur l'objet de requête principal ailleurs dans la page, alors oui! vous devez l'appeler pour vous assurer que l'objet de requête principal contient les données avant de parcourir votre requête personnalisée. Lorsque vous appelez la the_post()méthode (c'est-à-dire $my_custom_query->the_post()), vous remplissez les variables de post que la requête principale examine, la réinitialisation remplit ces variables avec les données précédentes lorsque vous l'appelez. Il est recommandé d'utiliser des réinitialisations après des requêtes personnalisées.
t31os

Réponses:

10

Salut @janoChen:

Réponse simple: non.

Ce qui suit est ce que le code PHP pour la fonction wp_reset_query()de /wp-includes/query.phpdans v3.0.4 WORDPRESS ainsi que les fonctions appelées par la suite. Vous pouvez voir qu'il s'agit principalement de modifier des variables globales.

Lorsque vous utilisez, new WP_Query($args)vous affecterez la valeur de retour des valeurs à une variable locale, donc, à moins que vous ne fassiez quelque chose de si complexe que vous connaissiez déjà la réponse à cette question, alors non, vous n'avez pas besoin d'appeler wp_reset_query():

function wp_reset_query() {
  unset($GLOBALS['wp_query']);
  $GLOBALS['wp_query'] =& $GLOBALS['wp_the_query'];
  wp_reset_postdata();
}

function wp_reset_postdata() {
  global $wp_query;
  if ( !empty($wp_query->post) ) {
    $GLOBALS['post'] = $wp_query->post;
    setup_postdata($wp_query->post);
  }
}

function setup_postdata($post) {
  global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages;

  $id = (int) $post->ID;

  $authordata = get_userdata($post->post_author);

  $day = mysql2date('d.m.y', $post->post_date, false);
  $currentmonth = mysql2date('m', $post->post_date, false);
  $numpages = 1;
  $page = get_query_var('page');
  if ( !$page )
    $page = 1;
  if ( is_single() || is_page() || is_feed() )
    $more = 1;
  $content = $post->post_content;
  if ( strpos( $content, '<!--nextpage-->' ) ) {
    if ( $page > 1 )
      $more = 1;
    $multipage = 1;
    $content = str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content);
    $content = str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content);
    $content = str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content);
    $pages = explode('<!--nextpage-->', $content);
    $numpages = count($pages);
  } else {
    $pages = array( $post->post_content );
    $multipage = 0;
  }

  do_action_ref_array('the_post', array(&$post));

  return true;
}

-Mike

MikeSchinkel
la source
@janoChen - heh. Il me pousse définitivement ces derniers temps, c'est sûr! Je suppose que comme on dit, la compétition améliore la race (mais ça m'empêche de faire quoi que ce soit d'autre de productif! '-)
MikeSchinkel
1
Juste pour ceux qui lisent ceci, car c'est toujours la réponse acceptée (la réponse de @ Rarst devrait être acceptée). Étant donné que l'OP utilise the_post()dans son code, les meilleures pratiques dictent qu'il doit utiliser wp_reset_postdata(). wp_reset_query()appels wp_reset_postdata(), ce qui fonctionnera, bien que l'autre chose wp_reset_query()- réinitialiser la $wp_queryvariable globale - ne soit pas nécessaire, mais pas nuisible dans ce cas. La réponse est donc OUI
Tom Auger
21

Ce n'est pas nécessaire pour WP_Querylui-même, mais il est nécessaire (ou du moins une bonne chose à faire) si vous utilisez des fonctions / méthodes connexes (telles que the_post()ou setup_postdata()) pour remplir des variables globales avec vos données.

Fondamentalement, la création d'un nouvel WP_Queryobjet est simplement une récupération de données, mais son utilisation pour exécuter la boucle active et rendre les données accessibles aux balises de modèle modifie l'environnement et il est bon de tout réinitialiser par la suite.

Dans l'ensemble - ce n'est pas une pénalité de performance significative de l'appeler, il est donc plus facile de toujours l'appeler que de décider si vous le devriez ou d'oublier et d'avoir quelque chose de mystérieusement cassé.

Mise à jour

wp_reset_postdata()la fonction semble être un choix plus approprié. wp_reset_query()réinitialise les variables globales $wp_query(quel WP_Queryobjet personnalisé n'affecte pas) et $post (qu'il pourrait comme ci-dessus) variables. wp_reset_postdata()restaure seulement $post, ce qui devrait être suffisant.

Rarst
la source
2

Non. Si vous instanciez votre propre objet WP_Query, c'est à vous de faire ce que vous voulez. Cependant, si vous trafiquez la global $wp_queryvariable, eh bien, votre dans l'espace de noms global affecte le script de toute personne qui utilise simultanément cette variable. Et si vous faites quelque chose pour modifier les données, vous devez également les réinitialiser après avoir fini de les utiliser.

RebelPhoenix
la source
0

Si vous utilisez une requête personnalisée comme celle-ci

$cat = new WP_query(); 
$cat->query("cat=19,20,-23&showposts=5&orderby=rand"); 
while ($cat->have_posts()) : $cat->the_post(); 
  $data = get_post_meta( $post->ID, 'key', true );
$img_arrays []= $data['productimage']; 
$lnk_arrays[] =get_permalink($post_ID); 
endwhile; 
wp_reset_query(); 

Vous ne rencontrerez alors aucun problème. Sinon, si sur la même page il y a une autre boucle, vous obtiendrez des résultats inattendus. Je n'ai pas utilisé wp_reset_query () dans le code ci-dessus (qui a été placé dans mon fichier header.php. Ensuite, quand je suis entré dans single.php, j'obtiens surtout les pages de détail d'autres catégories, ce qui était frustrant. Plus tard, j'ai réalisé que je J'ai oublié de réinitialiser la requête en haut. Bientôt, cela a commencé à fonctionner comme un charme.

Katie
la source