For some reason that's not quite clear, when I add custom query_vars, they become available everywhere without the need of an accessor like global or get_query_var()

// if your url contains the var http://example.com?document_id=99
// and you add it to $query_vars...
function filter__query_vars( $query_vars ) {
  $query_vars[] = 'document_id';
  return $query_vars;
add_filter( 'query_vars', 'filter__query_vars' );

// you can reference it anywhere.
/* single.php */
echo $document_id; // outputs 99. wtf?

Why does this work?

1 Answer 1


Within the WP::parse_request() method (src) we locate the query_vars filter:

$this->public_query_vars = apply_filters( 'query_vars', $this->public_query_vars );

and within WP::register_globals() we can see why it becomes globally accessible (src):

// Extract updated query vars back into global namespace.
foreach ( (array) $wp_query->query_vars as $key => $value ) {
    $GLOBALS[ $key ] = $value;

where the global $Wp_query has been fed with the query vars from the global $wp object.

  • 1
    This is the correct answer. By design, and history, and legacy code, query_vars are inherently global. They affect the query. The query is a global thing. If you don't want them global, don't make them query_vars. Additionally, if they don't directly affect the main WP_Query, then definitely don't make them query_vars.
    – Otto
    Apr 20, 2017 at 0:12
  • It looks like it's possible to override the global $wp_query and $wp objects through the query_vars filter with wp_query and wp as new custom query variables ;-) Maybe there should be a check for that to avoid total crash? @Otto
    – birgire
    Apr 20, 2017 at 1:29
  • No, there needs to be no check for that. Simply don't do that. You can override a lot of things the wrong way and thus break everything, but then you broke everything and it doesn't work, so what would be the point?
    – Otto
    Apr 20, 2017 at 12:27
  • yes, good point, too many ways to break things up anyway, like the globals ;-) @Otto
    – birgire
    Apr 20, 2017 at 21:03
  • Thanks for the explanation @birgire. I get it now. [@]Otto, this wasn't a problem, I just wanted to know why it worked. Apr 21, 2017 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.