web-dev-qa-db-fra.com

Pourquoi est-il nécessaire d'appeler rewind_posts () lorsque vous utilisez plusieurs fois la boucle?

La fonction rewind_posts est destinée à être utilisée lorsque la boucle sera appelée plusieurs fois dans une page avec la même requête.

Si j'appelle la même boucle une seconde fois dans la page, le résultat est identique à l'appel de la fonction rewind_posts juste avant.

Pourquoi est-ce nécessaire?Est-ce que rewind_posts n'appelle pas à nouveau le contenu de la base de données (le cache d'une manière ou d'une autre) lors de l'utilisation de la seconde boucle, sans utiliser rewind_posts, is?

3
Alvaro

Global 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: }

et rewind_posts à partir de WP_Query classe.

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:   }

peut nous aider à comprendre que nous sommes réellement dans le contexte de l'objet $wp_query lorsque nous sommesrewindingen utilisant le rewind_posts global.


Le pointeur codex que vous avez défini:

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

suggère que cela doit faire quelque chose avec la méthode $the_post.

Alors, quelle est la nature de 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 

Au moins, nous pouvons comprendre qu’un objet global $post est défini chaque fois que nous itérons la boucle while.

La clé pour comprendre est la méthode 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:   }

Cette méthode explique enfin que nous incrémentons le pointeur de publication actuel:

$this->current_post++;

Notez que dans l'expression ci-dessus, la variable entière $this->current_post sera incrémentée.

($this->current_post)++;

Ceci est équivalent à:

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

pour ceux qui n'aiment pas admettre la syntaxe, $this->current_post++; est plutôt cool d'incrémenter une variable.


Récapituler:

Depuis que nous avons appelé the_post() et augmenté le pointeur $this->current_post, nous devons maintenant définir ce pointeur sur -1 si nous prévoyons de boucler à nouveau.

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

Etrange assez, mais ça marche.

2
prosti