<div style="text-align:center"></div><div>
<p>WordPress 6.8 includes some caching optimizations that may affect themes and plugins using the <code>WP_Query::get()</code> method and the <code>WP_Query::$query_vars</code> property.</p>
<p>In <a href="https://core.trac.wordpress.org/ticket/59516">#59516</a>, <code>WP_Query</code> was optimized to improve cache hits for queries with equivalent arguments.</p>
<p>This enhancement improves performance for sites that run equivalent queries with a different order of arguments. The impact will be most noticeable on sites without a persistent cache, as these equivalent queries would run multiple times on a single page request, whereas they will now run once.</p>
<p>As such theme and plugin authors making use of filters within <code>WP_Query</code> (source code: <a href="https://github.com/WordPress/wordpress-develop/blob/6.8/src/wp-includes/class-wp-query.php">GitHub</a>, <a href="https://core.trac.wordpress.org/browser/branches/6.8/src/wp-includes/class-wp-query.php">trac</a>) are recommended to check their code for compatibility with WordPress 6.8. An example of code that would be affected by this is using equality to check for the contents of an array:</p>
<pre class="wp-block-code"><code lang="php" class="language-php">$query = new WP_Query( array( 'post_type' => array( 'post', 'page' ) ) );

add_filter( 'posts_where', function ( $where, $query ) {
 // True in WordPress 6.7, false in WordPress 6.8
 // WordPress 6.7 returns array( 'post', 'page' )
 // WordPress 6.8 returns array( 'page', 'post' )
 if ( array( 'post', 'page' ) === $query->get( 'post_type' ) ) {
 // Modify WHERE clause.
 }

 return $where;
}, 10, 2 );</code></pre>
<p>When comparing the contents of two arrays for <em>equivalence</em>, it is recommended to use the code <code>empty( array_diff( /* arrays */ ) )</code> rather than equality comparisons. See this <a href="https://3v4l.org/fAlcb">example for a demonstration</a>.</p>
<h2 class="wp-block-heading"><strong>Standardized arguments.</strong></h2>
<p>The most common example of where these changes will improve performance is when querying multiple post types:</p>
<pre class="wp-block-code"><code lang="php" class="language-php">$q1 = new WP_Query( [ 'post_type' => [ 'post', 'page' ] ] );
$q2 = new WP_Query( [ 'post_type' => [ 'page', 'post'] ] );
$q3 = new WP_Query( [ 'post_type' => [ 'page', 'post', 'post' ] ] );</code></pre>
<p>In WordPress 6.7 and earlier, these queries would each result in database queries as they were not seen as equivalent in the resulting database query and cache key.</p>
<p>To standardize equivalent queries, <code>WP_Query</code> now sorts and type casts arguments as appropriate. For each of the queries above the post types are sorted alphabetically and any duplicates removed. In WordPress 6.8 the <code>::get()</code> method and <code>::$query_vars</code> property will differ from the arguments passed to <code>$q1</code> and <code>$q3</code>:</p>
<pre class="wp-block-code"><code lang="php" class="language-php">$q1->get( 'post_type' ) // returns [ 'page', 'post' ]
$q2->get( 'post_type' ) // returns [ 'page', 'post' ]
$q3->get( 'post_type' ) // returns [ 'page', 'post' ]

$q1->query_vars['post_type'] === [ 'page', 'post' ]
$q2->query_vars['post_type'] === [ 'page', 'post' ]
$q3->query_vars['post_type'] === [ 'page', 'post' ]</code></pre>
<p>For items that accept values as either an integer or a string, these have been sorted and typecast as appropriate, for example <code>author__not_in => [ '2', '1' ]</code> becomes <code>author__not_in => [ 1, 2 ]</code>. A full list of affected arguments can be found in the commit message <a href="https://core.trac.wordpress.org/changeset/59766">[59766]</a>.</p>
<p>Due to differences in the code paths when the post type and status are passed as a string, these are not type cast to an array </p>
<pre class="wp-block-code"><code lang="php" class="language-php">$q4 = new WP_Query( [ 'post_type' => 'post' ] );
$q4->get( 'post_type' ) // returns 'post'</code></pre>
<p>These changes are part of an ongoing effort to <a href="https://make.wordpress.org/performance/">improve the performance of WordPress</a>. The core team are monitoring the changes for any major issues that may occur, see <a href="https://core.trac.wordpress.org/ticket/63255">#63255</a>. </p>
<p class="has-text-align-right">Props <a href="https://profiles.wordpress.org/joemcgill/" class="mention"><span class="mentions-prefix">@</span>joemcgill</a> and <a href="https://profiles.wordpress.org/jorbin/" class="mention"><span class="mentions-prefix">@</span>jorbin</a> for their review of this post.</p>
<p class="o2-appended-tags"><a href="https://make.wordpress.org/core/tag/6-8/" class="tag"><span class="tag-prefix">#</span>6-8</a>, <a href="https://make.wordpress.org/core/tag/dev-notes/" class="tag"><span class="tag-prefix">#</span>dev-notes</a>, <a href="https://make.wordpress.org/core/tag/dev-notes-6-8/" class="tag"><span class="tag-prefix">#</span>dev-notes-6-8</a>, <a href="https://make.wordpress.org/core/tag/performance/" class="tag"><span class="tag-prefix">#</span>performance</a></p>
</div>

The second Release Candidate (“RC2”) for WordPress 6.9 is ready for download and testing! This…
This post is the latest in a series of updates focused on the performance improvements…
The first Release Candidate (“RC1”) for WordPress 6.9 is ready for download and testing! This…
This story was produced in collaboration with Mark Szymanski and Adam Weeks. Check out Mark’s…
WordPress is moving closer to Google Docs-style collaborative editing. In an update on Phase 3…
The WordPress Foundation’s bid to trademark “Managed WordPress” and “Hosted WordPress” in the United States…