É necessário usar wp_reset_query () em uma chamada WP_Query?

26

Estou usando o seguinte código para recuperar postagens:

<?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; ?>

Preciso usar wp_reset_query()? Se sim, onde devo colocá-lo?

janoChen
fonte
2
Se você está confiando no objeto de consulta principal em outro lugar da página, então Sim! você deve chamá-lo para garantir que o objeto de consulta principal contenha os dados antes de iterar sua consulta personalizada. Quando você chama o the_post()método (ie. $my_custom_query->the_post()), Você reabastece as variáveis ​​de postagem que a consulta principal analisa, a redefinição reabastece esses vars com os dados anteriores quando você a chama. É uma boa prática usar redefinições após consultas personalizadas.
t31os 29/01

Respostas:

10

Oi @janoChen:

Resposta simples: não.

O que se segue é o que o código PHP para a função wp_reset_query()de /wp-includes/query.phpno WordPress v3.0.4, bem como as funções posteriormente chamado. Você pode ver que se trata principalmente de modificar variáveis ​​globais.

Ao usar, new WP_Query($args)você atribuirá o valor de retorno dos valores a uma variável local; portanto, a menos que esteja fazendo algo tão complexo que já saiba a resposta para essa pergunta, não será necessário chamar 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
fonte
@janoChen - heh. Ele definitivamente está me pressionando ultimamente, isso é certo! Eu acho que, como eles dizem, a concorrência melhora a raça (mas com certeza me impede de fazer qualquer outra coisa produtiva! ')
MikeSchinkel
11
Apenas para quem está lendo isso, já que essa ainda é a resposta aceita (a resposta de @ Rarst deve ser aceita). Como o OP usa the_post()em seu código, as práticas recomendadas determinam que ele deve usar wp_reset_postdata(). wp_reset_query()chamadas wp_reset_postdata(), para que funcione, embora a outra coisa funcione wp_reset_query()- redefinir a $wp_queryvariável global - não é necessário, mas não é prejudicial nesse caso. Portanto, a resposta é SIM
Tom Auger
21

Não é necessário WP_Querypor si só, mas é necessário (ou pelo menos uma coisa boa a fazer) se você usar quaisquer funções / métodos relacionados (como the_post()ou setup_postdata()) para preencher variáveis ​​globais com seus dados.

Basicamente, criar um novo WP_Queryobjeto é apenas recuperação de dados, mas usá-lo para executar um loop ativo e tornar os dados acessíveis às tags de modelo modifica o ambiente e é bom redefinir tudo posteriormente.

No geral - não é uma penalidade significativa de desempenho chamá-lo, por isso é mais fácil chamá-lo sempre do que decidir se deveria ou esquecê-lo e ter algo misteriosamente quebrado.

Atualizar

wp_reset_postdata()A função parece ser uma escolha mais adequada. wp_reset_query()redefine variáveis globais $wp_query(que WP_Queryobjeto personalizado não afeta) e $post (que podem ser acima) variáveis. wp_reset_postdata()apenas restaura $post, o que deve ser suficiente.

Rarst
fonte
2

Não. Se você instanciar seu próprio objeto WP_Query, é seu o que você deseja. No entanto, se você adulterar a global $wp_queryvariável, bem, você estará no espaço de nomes global, afetando o script de qualquer pessoa que esteja usando simultaneamente essa variável. E se você fizer algo para alterar os dados nele, também deverá redefini-lo após concluir o uso.

RebelPhoenix
fonte
0

Se você estiver usando uma consulta personalizada como esta

$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(); 

Então você não terá problemas. Caso contrário, se na mesma página houver outro loop, você será obrigado a obter resultados inesperados. Eu não usei wp_reset_query () no código acima (que foi colocado no meu arquivo header.php. Então, quando entrei no single.php, geralmente recebo as páginas de detalhes de outras categorias que eram frustrantes. Mais tarde, percebi que eu esqueci de redefinir a consulta no topo e logo começou a funcionar como um encanto.

Katie
fonte