Có cần thiết phải sử dụng wp_reset_query () trong cuộc gọi WP_Query không?


26

Tôi đang sử dụng đoạn mã sau để truy xuất bài viết:

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

Tôi có cần sử dụng wp_reset_query()không? Nếu tôi làm, tôi nên đặt nó ở đâu?



2
Nếu bạn đang dựa vào đối tượng truy vấn chính ở một nơi khác trong trang, thì Có! bạn nên gọi nó, để đảm bảo đối tượng truy vấn chính chứa dữ liệu được thực hiện trước khi bạn lặp lại truy vấn tùy chỉnh của mình. Khi bạn gọi the_post()phương thức (ví dụ. $my_custom_query->the_post()) Bạn nạp lại các biến bài đăng mà truy vấn chính sẽ xem xét, thiết lập lại sẽ nạp lại các vars này với dữ liệu trước đó khi bạn gọi nó. Đó là thực hành tốt để sử dụng đặt lại sau khi truy vấn tùy chỉnh.
t31os

Câu trả lời:


10

Xin chào @janoChen:

Câu trả lời đơn giản: không.

Phần tiếp theo là mã PHP cho hàm wp_reset_query()từ /wp-includes/query.phptrong WordPRess v3.0.4 cũng như các hàm được gọi sau đó. Bạn có thể thấy rằng chủ yếu là về việc sửa đổi các biến toàn cục.

Khi bạn sử dụng, new WP_Query($args)bạn sẽ gán giá trị trả về từ các giá trị cho biến cục bộ, vì vậy trừ khi bạn đang làm điều gì đó phức tạp đến mức bạn đã biết câu trả lời cho câu hỏi này rồi thì không, bạn không cần phải gọi 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;
}

-Như


@janoChen - heh. Anh ấy chắc chắn đã đẩy tôi gần đây, đó là điều chắc chắn! Tôi đoán như họ nói, cạnh tranh giúp cải thiện giống (nhưng chắc chắn giúp tôi không làm gì khác hiệu quả! '-)
MikeSchinkel

1
Chỉ dành cho những người khác đọc nó, vì đây vẫn là câu trả lời được chấp nhận (câu trả lời của @ Rarst nên được chấp nhận). Vì OP sử dụng the_post()mã của mình, các thực tiễn tốt nhất cho rằng anh ta phải sử dụng wp_reset_postdata(). wp_reset_query()các cuộc gọi wp_reset_postdata(), do đó sẽ hoạt động, mặc dù điều khác wp_reset_query()thực hiện - đặt lại $wp_querybiến toàn cục - là không cần thiết, nhưng không có hại trong trường hợp này. Vì vậy, câu trả lời thực sự là
Tom Auger

21

WP_QueryBản thân nó không cần thiết , nhưng nó là cần thiết (hoặc ít nhất là điều tốt để làm) nếu bạn sử dụng bất kỳ chức năng / phương thức liên quan nào (như the_post()hoặc setup_postdata()) để điền vào các biến toàn cục với dữ liệu của bạn.

Về cơ bản việc tạo WP_Queryđối tượng mới chỉ đơn thuần là truy xuất dữ liệu, nhưng sử dụng nó để chạy vòng lặp hoạt động và làm cho dữ liệu có thể truy cập được vào thẻ mẫu sẽ sửa đổi môi trường và tốt hơn là đặt lại mọi thứ sau đó.

Nhìn chung - đó không phải là hình phạt hiệu suất có ý nghĩa để gọi nó, vì vậy việc gọi nó dễ dàng hơn là quyết định xem bạn nên hay quên nó và có một cái gì đó bị phá vỡ một cách bí ẩn.

Cập nhật

wp_reset_postdata()chức năng dường như là sự lựa chọn phù hợp hơn. wp_reset_query()đặt lại các biến toàn cục $wp_query(mà WP_Queryđối tượng tùy chỉnh không ảnh hưởng) và các biến $post (có thể như trên). wp_reset_postdata()Chỉ khôi phục $post, mà nên là đủ.


2

Không. Nếu bạn khởi tạo đối tượng WP_Query của riêng bạn, thì đối tượng của bạn sẽ làm với những gì bạn sẽ làm. Tuy nhiên, nếu bạn can thiệp vào global $wp_querybiến, thì trong không gian tên toàn cầu của bạn ảnh hưởng đến tập lệnh của bất kỳ ai đang sử dụng đồng thời biến đó. Và nếu bạn làm gì đó để thay đổi dữ liệu trong đó, bạn cũng phải đặt lại dữ liệu đó sau khi sử dụng xong.


0

Nếu bạn đang sử dụng truy vấn tùy chỉnh như thế này

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

Sau đó, bạn sẽ không gặp vấn đề. Mặt khác, nếu trên cùng một trang có một vòng lặp khác, bạn nhất định sẽ nhận được một số kết quả không mong muốn. Tôi đã không sử dụng wp_reset_query () trong đoạn mã trên (được đặt trong tệp header.php của tôi. Sau đó, khi tôi vào single.php, tôi nhận được các trang chi tiết của các danh mục khác gây thất vọng. Sau đó, tôi nhận ra rằng tôi quên đặt lại truy vấn ở trên cùng. Ngay sau đó, nó bắt đầu hoạt động như một bùa mê.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.