web-dev-qa-db-ja.com

ループを2回以上使用するときにrewind_posts()を呼び出す必要があるのはなぜですか?

rewind_posts関数 は、ループが同じクエリを持つページ内で複数回呼び出される場合に使用されることを意図しています。

同じループをページ内でもう一度呼び出すと、結果は直前にrewind_posts関数を呼び出すのと同じになります。

な​​ぜ必要なのですか?rewind_postsを使わずに2番目のループを使っている間にrewind_postsがデータベース内のコンテンツを再度呼び出すことはありません(なんらかの方法でキャッシュします)。

3
Alvaro

グローバルrewind_posts

File: wp-includes/query.php
784: /**
785:  * Rewind the loop posts.
786:  *
787:  * @since 1.5.0
788:  *
789:  * @global WP_Query $wp_query Global WP_Query instance.
790:  */
791: function rewind_posts() {
792:    global $wp_query;
793:    $wp_query->rewind_posts();
794: }

rewind_postsクラスのWP_Query

File: wp-includes/class-wp-query.php
3144:    * Rewind the posts and reset post index.
3145:    *
3146:    * @since 1.5.0
3147:    * @access public
3148:    */
3149:   public function rewind_posts() {
3150:       $this->current_post = -1;
3151:       if ( $this->post_count > 0 ) {
3152:           $this->post = $this->posts[0];
3153:       }
3154:   }

グローバルな$wp_queryを使ってrewindingしているとき、私たちが実際にrewind_postsオブジェクトの文脈にいると理解するのに役立ちます。


設定した codex ポインター。

// main loop
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>

// rewind
<?php rewind_posts(); ?>

// new loop
<?php while (have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; ?>

これは$the_postメソッドで何かする必要があることを示唆しています。

それで、the_post()の性質は何ですか?

File: /class-wp-query.php
3095:   public function the_post() {
3096:       global $post;
3097:       $this->in_the_loop = true;
3098: 
3099:       if ( $this->current_post == -1 ) // loop has just started
3100:           /**
3101:            * Fires once the loop is started.
3102:            *
3103:            * @since 2.0.0
3104:            *
3105:            * @param WP_Query &$this The WP_Query instance (passed by reference).
3106:            */
3107:           do_action_ref_array( 'loop_start', array( &$this ) );
3108: 
3109:       $post = $this->next_post();
3110:       $this->setup_postdata( $post );
3111:   }

enter image description here 

whileループを繰り返すたびにglobal $postオブジェクトが設定されることを少なくとも理解できます。

理解の鍵はnext_post()メソッドです。

File: wp-includes/class-wp-query.php
3068:   /**
3069:    * Set up the next post and iterate current post index.
3070:    *
3071:    * @since 1.5.0
3072:    * @access public
3073:    *
3074:    * @return WP_Post Next post.
3075:    */
3076:   public function next_post() {
3077: 
3078:       $this->current_post++;
3079: 
3080:       $this->post = $this->posts[$this->current_post];
3081:       return $this->post;
3082:   }

このメソッドは、最後に現在のポストポインタをインクリメントすることを説明しています。

$this->current_post++;

上記の式では、変数$this->current_post全体がインクリメントされます。

($this->current_post)++;

これは以下と同等です。

$this->current_post = $this->current_post + 1;

構文$this->current_post++;を認めたくない人は、変数をインクリメントするのはかなりクールです。


要点をまとめると:

the_post()を呼び出して$this->current_postポインタを増やしたので、次にループする予定がある場合は、このポインタを-1に設定する必要があります。

3149:   public function rewind_posts() {
3150:       $this->current_post = -1;
3151:       if ( $this->post_count > 0 ) {
3152:           $this->post = $this->posts[0];
3153:       }
3154:   }

奇妙なことだが、うまくいく。

2
prosti