You Don't Know Query - WordCamp Portland 2011

WordCamp Portland 2011
September 17, 2011
Andrew Nacin
Core Developer of WordPress
Tech Ninja at Audrey Capital
nacin@wordpress.org
@nacin on Twitter
You Don't Know Query
What do you know?
Conditional Tags


is_author( ), is_home( ), etc.
Who has ever heard of
query_posts( )?
Ways to query

query_posts( )
new WP_Query( )
get_posts( )
The loop

if ( have_posts( ) )
   while ( have_posts( ) ) :
      the_post( );

  endwhile( );
What don't you know?
Every query object has its
own methods
is_author( ) is the same as calling
$wp_query->is_author( )
function is_author( ) {
  global $wp_query;

    return $wp_query->is_author( );
}
If you do:
$my_query = new WP_Query( $query );

You can do:
while ( $my_query->have_posts( ) ) :
 $my_query->the_post( );
endwhile;
wp_reset_postdata( );
But why do we call things like
wp_reset_postdata( ) and
wp_reset_query( )?

What about using query_posts( )?

How can you alter a query? What
about the main query?
What is the main query,
and why should I care?
Let's dig in.
wp-blog-header.php
// Load the WordPress bootstrap
require dirname( __FILE__ ) . '/wp-load.php';

// Do magic
wp();

// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
Let's look in the bootstrap:

$wp_the_query = new WP_Query();
$wp_query =& $wp_the_query;
Quick lesson on PHP references
$a = 4;
$b =& $a;
$b = 2;
var_dump( $a ); // int(2)
$a = 6;
var_dump( $b ); // int(6)
So:
So the real main query is in
$wp_the_query.

And a live copy of it is stored in
$wp_query.
wp-blog-header.php
// Load the WordPress bootstrap
require dirname( __FILE__ ) . '/wp-load.php';

// Do magic
wp();

// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
wp-blog-header.php
// Load the WordPress bootstrap
require dirname( __FILE__ ) . '/wp-load.php';

// Do magic
wp( );

// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
What is that wp( ) call?

function wp( $query_vars = '' ) {
  global $wp;

    $wp->main( $query_vars );
}
Holy $!@?, what just
happened?
In the bootstrap:

$wp = new WP( );

So there's a wp( ) function,
and a WP class.
class WP {
    . . .
    function main( ) {
        $this->init( );
        $this->parse_request( );
        $this->send_headers( );
        $this->query_posts( );
        $this->handle_404( );
        $this->register_globals( );
   . . .
class WP {
    . . .
    function main( ) {
        $this->init( );
        $this->parse_request( );
        $this->send_headers( );
        $this->query_posts( );
        $this->handle_404( );
        $this->register_globals( );
   . . .
WP::parse_request( )
— Parses the URL using WP_Rewrite
— Sets up query variables for WP_Query

WP::query_posts( ) {
  global $wp_the_query;
  $wp_the_query->query( $this->query_vars );
}
Boom.
SELECT SQL_CALC_FOUND_ROWS
  wp_posts.*
FROM wp_posts
WHERE 1=1
  AND wp_posts.post_type = 'post'
  AND wp_posts.post_status = 'publish'
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
wp-blog-header.php

// Load WordPress.
require dirname(__FILE__) . '/wp-load.php';

// Parse what to query, and query it.
wp();

// Load the theme.
ABSPATH . WPINC . '/template-loader.php';
Before we get to the theme,
we have your posts.

Got it?
Then why do we do this?

query_posts( 'author=5' );
get_header( );
while( have_posts( ) ) :
  the_post( );
endwhile;
get_footer( );
That's running 2* queries!

One, the query WordPress
thought we wanted.

Two, this new one you're
actually going to use.
* Actually, WP_Query
doesn't run just one query.
It usually runs four.
1. Get me my posts:
     SELECT
     SQL_CALC_FOUND_ROWS …
     FROM wp_posts LIMIT 0, 10
2. How many posts exist?
     SELECT FOUND_ROWS()
3. Slurp all metadata for these posts.
4. Slurp all terms for these posts.
PROTIP
‘Measure twice, cut once’
is bad for performance.
(A note, you can turn these off selectively…)

$my_query = new WP_Query( array(
     'no_found_rows' => true,
     'update_post_meta_cache' => false,
     'update_post_term_cache' => false,
) );
So. Instead of this:

query_posts( 'author=5' );
get_header( );
while ( have_posts( ) ) :
  the_post( );
endwhile;
get_footer( );
We can use this:

// In WP::parse_request()

$this->query_vars =
   apply_filters( 'request', $this->query_vars );
We can modify query
variables in mid air:
function nacin_filter_out_author( $qvs ) {
  if ( ! isset( $qvs['author'] ) )
          $qvs['author'] = '-5';
  return $qvs;
}
Powerful, but lacks context.
Powerful, but lacks context.

Problem 1: Conditional tags don't work yet.
Powerful, but lacks context.

Problem 1: Conditional tags don't work yet.

Problem 2: Only works on the main query.
Powerful, but lacks context.

Problem 1: Conditional tags don't work yet.

Problem 2: Only works on the main query.

Problem 3: WP_Query is waaay cooler.
Introducing pre_get_posts
class WP_Query {
   . . .
   function &get_posts() {
       $this->parse_query();
       // Huzzah! Conditional tags are available.
       do_action_ref_array( 'pre_get_posts',
          array( &$this ) );
   . . .
A truly awesome hook.

function nacin_alter_home( $query ) {
  if ( $query->is_home( ) )
         $query->set( 'author', '-5' );
}
add_action( 'pre_get_posts', 'nacin_alter_home' );
Still with us?


Good, ‘cause here’s where
things get hairy.
'request' fires for the main query only.

'pre_get_posts' fires for every post query:
— get_posts()
— new WP_Query()
— That random recent posts widget.
— Everything.
What if I just want it on the
main query?
$wp_the_query makes a
triumphant return.
Main query only!

function nacin_alter_home ( $query ) {
  if ( $wp_the_query === $query
             && $query->is_home() )
                  $query->set( 'author', '-5' );
}
add_action( 'pre_get_posts', 'nacin_alter_home' );
Hmm. How does this work?

$wp_the_query should never be modified. It
holds the main query, forever.

$wp_query keeps a live reference to
$wp_the_query, unless you use query_posts().
query_posts( 'author=-5' );
while ( have_posts( ) ) :
  the_post( );
endwhile;
wp_reset_query( );
query_posts( 'author=-5' );
while ( have_posts( ) ) :
  the_post( );
endwhile;
wp_reset_query( );
class WP_Query {
   . . .
   function &query_posts( $query ) {
         // Break the reference to $wp_the_query
         unset( $wp_query );
         $wp_query =& new WP_Query( $query );
         . . .
query_posts( 'author=-5' );
while ( have_posts( ) ) :
  the_post( );
endwhile;
wp_reset_query( );
class WP_Query {
   . . .
       function wp_reset_query( ) {
           // Restore the reference to
$wp_the_query
           unset( $wp_query );
           $wp_query =& $wp_the_query;
       // Reset the globals, too.
           wp_reset_postdata( );
       . . .
Calling the_post( )?
  wp_reset_query( ) will reset $wp_query
  and and the globals.

Calling $my_query->the_post( )?
  wp_reset_postdata( ) will reset the globals.
New thing for core in 3.3!
Rather than:
     $wp_the_query === $other_query_object
	
  
You'll be able to call:
     $other_query_object->is_main_query( )
	
  
is_main_query( ), the function, will act on
$wp_query, like any other conditional tag.
Some Lessons
Every WP_Query object has methods that
mimic the global conditional tags.

The global conditional tags apply to
$wp_query, the main or current query.

$wp_query is always the main query, unless
you use query_posts( ). Restore it with
wp_reset_query( ).
And Finally
request is a nice hook. pre_get_posts is more
powerful and flexible. Just use it properly.

Always check if you're modifying the main query
using $query === $wp_the_query

$query->is_main_query( ) in 3.3!
Thanks! Questions?


@nacin
1 of 61

Recommended

You Don't Know Query (WordCamp Netherlands 2012) by
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)andrewnacin
62.3K views69 slides
Database Anti Patterns by
Database Anti PatternsDatabase Anti Patterns
Database Anti PatternsRobert Treat
10.1K views52 slides
AOS Lab 2: Hello, xv6! by
AOS Lab 2: Hello, xv6!AOS Lab 2: Hello, xv6!
AOS Lab 2: Hello, xv6!Zubair Nabi
9.1K views25 slides
Olivia Li Chinese Local Seninar - 11th mar by
Olivia Li Chinese Local Seninar - 11th marOlivia Li Chinese Local Seninar - 11th mar
Olivia Li Chinese Local Seninar - 11th marPeter Chen
1K views115 slides
Flask Introduction - Python Meetup by
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python MeetupAreski Belaid
4.4K views15 slides
Going realtime with Socket.IO by
Going realtime with Socket.IOGoing realtime with Socket.IO
Going realtime with Socket.IOChristian Joudrey
7.6K views22 slides

More Related Content

Similar to You Don't Know Query - WordCamp Portland 2011

You don’t know query - WordCamp UK Edinburgh 2012 by
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012l3rady
978 views53 slides
WordPress London 16 May 2012 - You don’t know query by
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryl3rady
1.1K views53 slides
Wp query by
Wp queryWp query
Wp querySavita Soni
6.6K views33 slides
The Query the Whole Query and Nothing but the Query by
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryChris Olbekson
1.2K views66 slides
WordPress Queries - the right way by
WordPress Queries - the right wayWordPress Queries - the right way
WordPress Queries - the right wayAnthony Hortin
3.8K views49 slides
Getting Creative with WordPress Queries by
Getting Creative with WordPress QueriesGetting Creative with WordPress Queries
Getting Creative with WordPress QueriesDrewAPicture
4.8K views41 slides

Similar to You Don't Know Query - WordCamp Portland 2011(20)

You don’t know query - WordCamp UK Edinburgh 2012 by l3rady
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012
l3rady978 views
WordPress London 16 May 2012 - You don’t know query by l3rady
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know query
l3rady1.1K views
The Query the Whole Query and Nothing but the Query by Chris Olbekson
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
Chris Olbekson1.2K views
WordPress Queries - the right way by Anthony Hortin
WordPress Queries - the right wayWordPress Queries - the right way
WordPress Queries - the right way
Anthony Hortin3.8K views
Getting Creative with WordPress Queries by DrewAPicture
Getting Creative with WordPress QueriesGetting Creative with WordPress Queries
Getting Creative with WordPress Queries
DrewAPicture4.8K views
Getting Creative with WordPress Queries, Again by DrewAPicture
Getting Creative with WordPress Queries, AgainGetting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, Again
DrewAPicture515 views
WP_Query, pre_get_posts, and eliminating query_posts() by Erick Hitter
WP_Query, pre_get_posts, and eliminating query_posts()WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()
Erick Hitter8.3K views
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014 by Cliff Seal
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Cliff Seal5K views
Как получить чёрный пояс по WordPress? v2.0 by Yevhen Kotelnytskyi
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? by Yevhen Kotelnytskyi
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
Yevhen Kotelnytskyi1.6K views
Your code sucks, let's fix it - DPC UnCon by Rafael Dohms
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
Rafael Dohms32.5K views
[WLDN] Supercharging word press development in 2018 by Adam Tomat
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
Adam Tomat291 views
You code sucks, let's fix it by Rafael Dohms
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
Rafael Dohms56.4K views
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014 by Cliff Seal
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Cliff Seal1.6K views
Custom Database Queries in WordPress by topher1kenobe
Custom Database Queries in WordPressCustom Database Queries in WordPress
Custom Database Queries in WordPress
topher1kenobe4.9K views
WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress by WordCamp Kyiv
WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress
WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress
WordCamp Kyiv340 views

More from andrewnacin

Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ... by
Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...
Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...andrewnacin
1.9K views89 slides
WordCamp Netherlands 2012: WordPress in 2012 by
WordCamp Netherlands 2012: WordPress in 2012WordCamp Netherlands 2012: WordPress in 2012
WordCamp Netherlands 2012: WordPress in 2012andrewnacin
2.5K views74 slides
WordCamp SF 2011: Debugging in WordPress by
WordCamp SF 2011: Debugging in WordPressWordCamp SF 2011: Debugging in WordPress
WordCamp SF 2011: Debugging in WordPressandrewnacin
3.9K views53 slides
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul... by
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...andrewnacin
4.3K views27 slides
Open Source (and you can too) - 2011 Teens in Tech Conference by
Open Source (and you can too) - 2011 Teens in Tech ConferenceOpen Source (and you can too) - 2011 Teens in Tech Conference
Open Source (and you can too) - 2011 Teens in Tech Conferenceandrewnacin
1.2K views46 slides
WordCamp Columbus 2011 - What's Next for WordPress by
WordCamp Columbus 2011 - What's Next for WordPressWordCamp Columbus 2011 - What's Next for WordPress
WordCamp Columbus 2011 - What's Next for WordPressandrewnacin
894 views84 slides

More from andrewnacin(17)

Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ... by andrewnacin
Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...
Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...
andrewnacin1.9K views
WordCamp Netherlands 2012: WordPress in 2012 by andrewnacin
WordCamp Netherlands 2012: WordPress in 2012WordCamp Netherlands 2012: WordPress in 2012
WordCamp Netherlands 2012: WordPress in 2012
andrewnacin2.5K views
WordCamp SF 2011: Debugging in WordPress by andrewnacin
WordCamp SF 2011: Debugging in WordPressWordCamp SF 2011: Debugging in WordPress
WordCamp SF 2011: Debugging in WordPress
andrewnacin3.9K views
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul... by andrewnacin
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
andrewnacin4.3K views
Open Source (and you can too) - 2011 Teens in Tech Conference by andrewnacin
Open Source (and you can too) - 2011 Teens in Tech ConferenceOpen Source (and you can too) - 2011 Teens in Tech Conference
Open Source (and you can too) - 2011 Teens in Tech Conference
andrewnacin1.2K views
WordCamp Columbus 2011 - What's Next for WordPress by andrewnacin
WordCamp Columbus 2011 - What's Next for WordPressWordCamp Columbus 2011 - What's Next for WordPress
WordCamp Columbus 2011 - What's Next for WordPress
andrewnacin894 views
TEDxYouth@DowntownDC by andrewnacin
TEDxYouth@DowntownDCTEDxYouth@DowntownDC
TEDxYouth@DowntownDC
andrewnacin821 views
Best Practices in Plugin Development (WordCamp Seattle) by andrewnacin
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
andrewnacin27.1K views
Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle) by andrewnacin
Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)
Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)
andrewnacin4.8K views
Hidden Features (WordPress DC) by andrewnacin
Hidden Features (WordPress DC)Hidden Features (WordPress DC)
Hidden Features (WordPress DC)
andrewnacin644 views
Lightning Talk: Mistakes (WordCamp Phoenix 2011) by andrewnacin
Lightning Talk: Mistakes (WordCamp Phoenix 2011)Lightning Talk: Mistakes (WordCamp Phoenix 2011)
Lightning Talk: Mistakes (WordCamp Phoenix 2011)
andrewnacin2.6K views
WordPress at Web Content Mavens (Jan. 2011) by andrewnacin
WordPress at Web Content Mavens (Jan. 2011)WordPress at Web Content Mavens (Jan. 2011)
WordPress at Web Content Mavens (Jan. 2011)
andrewnacin1K views
WordPress 3.1 at DC PHP by andrewnacin
WordPress 3.1 at DC PHPWordPress 3.1 at DC PHP
WordPress 3.1 at DC PHP
andrewnacin1.1K views
What's Next for WordPress at WordCamp Netherlands by andrewnacin
What's Next for WordPress at WordCamp NetherlandsWhat's Next for WordPress at WordCamp Netherlands
What's Next for WordPress at WordCamp Netherlands
andrewnacin1.2K views
What's Next for WordPress: WordCamp Birmingham 2010 by andrewnacin
What's Next for WordPress: WordCamp Birmingham 2010What's Next for WordPress: WordCamp Birmingham 2010
What's Next for WordPress: WordCamp Birmingham 2010
andrewnacin1.3K views
WordPress 3.0 at DC PHP by andrewnacin
WordPress 3.0 at DC PHPWordPress 3.0 at DC PHP
WordPress 3.0 at DC PHP
andrewnacin1.6K views
Advanced and Hidden WordPress APIs by andrewnacin
Advanced and Hidden WordPress APIsAdvanced and Hidden WordPress APIs
Advanced and Hidden WordPress APIs
andrewnacin1.6K views

Recently uploaded

Data Integrity for Banking and Financial Services by
Data Integrity for Banking and Financial ServicesData Integrity for Banking and Financial Services
Data Integrity for Banking and Financial ServicesPrecisely
12 views26 slides
PRODUCT LISTING.pptx by
PRODUCT LISTING.pptxPRODUCT LISTING.pptx
PRODUCT LISTING.pptxangelicacueva6
13 views1 slide
Network Source of Truth and Infrastructure as Code revisited by
Network Source of Truth and Infrastructure as Code revisitedNetwork Source of Truth and Infrastructure as Code revisited
Network Source of Truth and Infrastructure as Code revisitedNetwork Automation Forum
25 views45 slides
20231123_Camunda Meetup Vienna.pdf by
20231123_Camunda Meetup Vienna.pdf20231123_Camunda Meetup Vienna.pdf
20231123_Camunda Meetup Vienna.pdfPhactum Softwareentwicklung GmbH
33 views73 slides
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive by
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLiveAutomating a World-Class Technology Conference; Behind the Scenes of CiscoLive
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLiveNetwork Automation Forum
30 views35 slides
Unit 1_Lecture 2_Physical Design of IoT.pdf by
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdfStephenTec
12 views36 slides

Recently uploaded(20)

Data Integrity for Banking and Financial Services by Precisely
Data Integrity for Banking and Financial ServicesData Integrity for Banking and Financial Services
Data Integrity for Banking and Financial Services
Precisely12 views
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive by Network Automation Forum
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLiveAutomating a World-Class Technology Conference; Behind the Scenes of CiscoLive
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive
Unit 1_Lecture 2_Physical Design of IoT.pdf by StephenTec
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdf
StephenTec12 views
Igniting Next Level Productivity with AI-Infused Data Integration Workflows by Safe Software
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Safe Software257 views
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 by IttrainingIttraining
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
PharoJS - Zürich Smalltalk Group Meetup November 2023 by Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi126 views
Business Analyst Series 2023 - Week 3 Session 5 by DianaGray10
Business Analyst Series 2023 -  Week 3 Session 5Business Analyst Series 2023 -  Week 3 Session 5
Business Analyst Series 2023 - Week 3 Session 5
DianaGray10237 views
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by James Anderson
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
James Anderson66 views
Attacking IoT Devices from a Web Perspective - Linux Day by Simone Onofri
Attacking IoT Devices from a Web Perspective - Linux Day Attacking IoT Devices from a Web Perspective - Linux Day
Attacking IoT Devices from a Web Perspective - Linux Day
Simone Onofri15 views

You Don't Know Query - WordCamp Portland 2011

  • 2. Andrew Nacin Core Developer of WordPress Tech Ninja at Audrey Capital nacin@wordpress.org @nacin on Twitter
  • 4. What do you know?
  • 6. Who has ever heard of query_posts( )?
  • 7. Ways to query query_posts( ) new WP_Query( ) get_posts( )
  • 8. The loop if ( have_posts( ) ) while ( have_posts( ) ) : the_post( ); endwhile( );
  • 10. Every query object has its own methods is_author( ) is the same as calling $wp_query->is_author( )
  • 11. function is_author( ) { global $wp_query; return $wp_query->is_author( ); }
  • 12. If you do: $my_query = new WP_Query( $query ); You can do: while ( $my_query->have_posts( ) ) : $my_query->the_post( ); endwhile; wp_reset_postdata( );
  • 13. But why do we call things like wp_reset_postdata( ) and wp_reset_query( )? What about using query_posts( )? How can you alter a query? What about the main query?
  • 14. What is the main query, and why should I care?
  • 16. wp-blog-header.php // Load the WordPress bootstrap require dirname( __FILE__ ) . '/wp-load.php'; // Do magic wp(); // Decide which template files to load ABSPATH . WPINC . '/template-loader.php';
  • 17. Let's look in the bootstrap: $wp_the_query = new WP_Query(); $wp_query =& $wp_the_query;
  • 18. Quick lesson on PHP references $a = 4; $b =& $a; $b = 2; var_dump( $a ); // int(2) $a = 6; var_dump( $b ); // int(6)
  • 19. So: So the real main query is in $wp_the_query. And a live copy of it is stored in $wp_query.
  • 20. wp-blog-header.php // Load the WordPress bootstrap require dirname( __FILE__ ) . '/wp-load.php'; // Do magic wp(); // Decide which template files to load ABSPATH . WPINC . '/template-loader.php';
  • 21. wp-blog-header.php // Load the WordPress bootstrap require dirname( __FILE__ ) . '/wp-load.php'; // Do magic wp( ); // Decide which template files to load ABSPATH . WPINC . '/template-loader.php';
  • 22. What is that wp( ) call? function wp( $query_vars = '' ) { global $wp; $wp->main( $query_vars ); }
  • 23. Holy $!@?, what just happened?
  • 24. In the bootstrap: $wp = new WP( ); So there's a wp( ) function, and a WP class.
  • 25. class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
  • 26. class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
  • 27. WP::parse_request( ) — Parses the URL using WP_Rewrite — Sets up query variables for WP_Query WP::query_posts( ) { global $wp_the_query; $wp_the_query->query( $this->query_vars ); }
  • 28. Boom. SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND wp_posts.post_status = 'publish' ORDER BY wp_posts.post_date DESC LIMIT 0, 10
  • 29. wp-blog-header.php // Load WordPress. require dirname(__FILE__) . '/wp-load.php'; // Parse what to query, and query it. wp(); // Load the theme. ABSPATH . WPINC . '/template-loader.php';
  • 30. Before we get to the theme, we have your posts. Got it?
  • 31. Then why do we do this? query_posts( 'author=5' ); get_header( ); while( have_posts( ) ) : the_post( ); endwhile; get_footer( );
  • 32. That's running 2* queries! One, the query WordPress thought we wanted. Two, this new one you're actually going to use.
  • 33. * Actually, WP_Query doesn't run just one query. It usually runs four.
  • 34. 1. Get me my posts: SELECT SQL_CALC_FOUND_ROWS … FROM wp_posts LIMIT 0, 10 2. How many posts exist? SELECT FOUND_ROWS() 3. Slurp all metadata for these posts. 4. Slurp all terms for these posts.
  • 35. PROTIP ‘Measure twice, cut once’ is bad for performance.
  • 36. (A note, you can turn these off selectively…) $my_query = new WP_Query( array( 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) );
  • 37. So. Instead of this: query_posts( 'author=5' ); get_header( ); while ( have_posts( ) ) : the_post( ); endwhile; get_footer( );
  • 38. We can use this: // In WP::parse_request() $this->query_vars = apply_filters( 'request', $this->query_vars );
  • 39. We can modify query variables in mid air: function nacin_filter_out_author( $qvs ) { if ( ! isset( $qvs['author'] ) ) $qvs['author'] = '-5'; return $qvs; }
  • 41. Powerful, but lacks context. Problem 1: Conditional tags don't work yet.
  • 42. Powerful, but lacks context. Problem 1: Conditional tags don't work yet. Problem 2: Only works on the main query.
  • 43. Powerful, but lacks context. Problem 1: Conditional tags don't work yet. Problem 2: Only works on the main query. Problem 3: WP_Query is waaay cooler.
  • 44. Introducing pre_get_posts class WP_Query { . . . function &get_posts() { $this->parse_query(); // Huzzah! Conditional tags are available. do_action_ref_array( 'pre_get_posts', array( &$this ) ); . . .
  • 45. A truly awesome hook. function nacin_alter_home( $query ) { if ( $query->is_home( ) ) $query->set( 'author', '-5' ); } add_action( 'pre_get_posts', 'nacin_alter_home' );
  • 46. Still with us? Good, ‘cause here’s where things get hairy.
  • 47. 'request' fires for the main query only. 'pre_get_posts' fires for every post query: — get_posts() — new WP_Query() — That random recent posts widget. — Everything.
  • 48. What if I just want it on the main query?
  • 50. Main query only! function nacin_alter_home ( $query ) { if ( $wp_the_query === $query && $query->is_home() ) $query->set( 'author', '-5' ); } add_action( 'pre_get_posts', 'nacin_alter_home' );
  • 51. Hmm. How does this work? $wp_the_query should never be modified. It holds the main query, forever. $wp_query keeps a live reference to $wp_the_query, unless you use query_posts().
  • 52. query_posts( 'author=-5' ); while ( have_posts( ) ) : the_post( ); endwhile; wp_reset_query( );
  • 53. query_posts( 'author=-5' ); while ( have_posts( ) ) : the_post( ); endwhile; wp_reset_query( );
  • 54. class WP_Query { . . . function &query_posts( $query ) { // Break the reference to $wp_the_query unset( $wp_query ); $wp_query =& new WP_Query( $query ); . . .
  • 55. query_posts( 'author=-5' ); while ( have_posts( ) ) : the_post( ); endwhile; wp_reset_query( );
  • 56. class WP_Query { . . . function wp_reset_query( ) { // Restore the reference to $wp_the_query unset( $wp_query ); $wp_query =& $wp_the_query; // Reset the globals, too. wp_reset_postdata( ); . . .
  • 57. Calling the_post( )? wp_reset_query( ) will reset $wp_query and and the globals. Calling $my_query->the_post( )? wp_reset_postdata( ) will reset the globals.
  • 58. New thing for core in 3.3! Rather than: $wp_the_query === $other_query_object   You'll be able to call: $other_query_object->is_main_query( )   is_main_query( ), the function, will act on $wp_query, like any other conditional tag.
  • 59. Some Lessons Every WP_Query object has methods that mimic the global conditional tags. The global conditional tags apply to $wp_query, the main or current query. $wp_query is always the main query, unless you use query_posts( ). Restore it with wp_reset_query( ).
  • 60. And Finally request is a nice hook. pre_get_posts is more powerful and flexible. Just use it properly. Always check if you're modifying the main query using $query === $wp_the_query $query->is_main_query( ) in 3.3!