Cannot access values from get_query_var() in Wordpress

Learn cannot access values from get_query_var() in wordpress with practical examples, diagrams, and best practices. Covers php, wordpress development techniques with visual explanations.

Troubleshooting get_query_var() in WordPress: Accessing URL Parameters

Hero image for Cannot access values from get_query_var() in Wordpress

Learn why get_query_var() might not be returning expected values in WordPress and how to correctly register and retrieve custom URL parameters.

WordPress's get_query_var() function is a powerful tool for retrieving variables from the URL query string, which are often used for pagination, custom post type archives, or filtering content. However, developers frequently encounter issues where this function returns null or an empty string, even when the variable appears to be present in the URL. This article will demystify get_query_var(), explain common pitfalls, and provide robust solutions for correctly accessing your custom query variables.

Understanding WordPress Query Variables

WordPress processes URLs through its rewrite rules, transforming user-friendly permalinks into internal query variables that it can understand. When you use get_query_var(), you're asking WordPress to retrieve one of these internally recognized variables. The key to successful retrieval is ensuring that WordPress knows about your custom variable before it tries to process the URL.

flowchart TD
    A[User visits URL] --> B{"Is variable registered with WordPress?"}
    B -- Yes --> C[WordPress parses URL and sets query vars]
    C --> D["get_query_var('your_var')" returns value]
    B -- No --> E[WordPress ignores unknown variable]
    E --> F["get_query_var('your_var')" returns null/empty]
    F --> G[Problem: Variable not accessible]

Flowchart illustrating the WordPress query variable recognition process.

The Core Problem: Unregistered Query Variables

The most common reason get_query_var() fails is that the custom query variable you're trying to access has not been explicitly registered with WordPress. WordPress has a predefined list of public query variables (like paged, cat, tag, s, etc.). Any variable not on this list is simply ignored during the URL parsing process, making it inaccessible via get_query_var().

Solution 1: Registering Custom Query Variables

To make WordPress aware of your custom query variable, you need to add it to the list of recognized public query variables using the query_vars filter. This filter allows you to modify the array of public query variables before WordPress processes the URL.

<?php
function add_custom_query_vars( $vars ) {
    $vars[] = 'my_custom_var'; // Add your custom variable name here
    $vars[] = 'another_var';   // You can add multiple variables
    return $vars;
}
add_filter( 'query_vars', 'add_custom_query_vars' );

// Example of accessing the variable later
function display_custom_var_content() {
    $my_var_value = get_query_var( 'my_custom_var' );
    if ( ! empty( $my_var_value ) ) {
        echo '<p>My Custom Variable Value: ' . esc_html( $my_var_value ) . '</p>';
    }
}
add_action( 'wp_head', 'display_custom_var_content' );
?>

Registering custom query variables using the query_vars filter.

Solution 2: Flushing Rewrite Rules (When Necessary)

After registering new query variables, especially if you're also adding custom rewrite rules, it's often necessary to flush WordPress's rewrite rules. This rebuilds the internal rules cache, ensuring that your new variables are properly recognized. You can do this programmatically or manually.

Add flush_rewrite_rules(); to your plugin activation hook or theme setup. Important: Only run this once, not on every page load, as it's resource-intensive. Remove it after the first successful flush.

2. Manual Flush (Easiest for development)

Navigate to Settings > Permalinks in your WordPress admin dashboard and simply click 'Save Changes' without making any modifications. This action triggers a rewrite rule flush.

Solution 3: Handling Custom Rewrite Rules for Pretty URLs

If you want to use pretty URLs (e.g., /my-page/my_custom_var_value/) instead of query string parameters (e.g., /my-page/?my_custom_var=my_custom_var_value), you'll need to combine query_vars with add_rewrite_rule(). This tells WordPress how to interpret the URL structure and map parts of it to your registered query variables.

<?php
// 1. Register the custom query var
function custom_add_query_vars( $vars ) {
    $vars[] = 'product_category';
    return $vars;
}
add_filter( 'query_vars', 'custom_add_query_vars' );

// 2. Add a rewrite rule
function custom_add_rewrite_rules() {
    add_rewrite_rule(
        '^products/([^/]+)/?$', // Regex to match the URL structure
        'index.php?pagename=products&product_category=$matches[1]', // How to map to query vars
        'top' // Position of the rule
    );
}
add_action( 'init', 'custom_add_rewrite_rules' );

// 3. Flush rewrite rules (do this once after adding/modifying rules)
// function custom_flush_rewrites() {
//     custom_add_rewrite_rules(); // Ensure rules are added before flushing
//     flush_rewrite_rules();
// }
// register_activation_hook( __FILE__, 'custom_flush_rewrites' );

// Example of accessing the variable on the 'products' page
function display_product_category() {
    if ( is_page( 'products' ) ) {
        $category = get_query_var( 'product_category' );
        if ( ! empty( $category ) ) {
            echo '<h2>Showing products for category: ' . esc_html( $category ) . '</h2>';
        } else {
            echo '<h2>Showing all products</h2>';
        }
    }
}
add_action( 'wp_head', 'display_product_category' );
?>

Combining query_vars with add_rewrite_rule() for pretty URLs.

Alternative: Direct Access to $_GET (Use with Caution)

For simple, non-pretty URL query parameters (e.g., example.com/?my_param=value), you can directly access the $_GET superglobal. However, this bypasses WordPress's sanitization and internal query processing, which can lead to security vulnerabilities if not handled carefully. It's generally recommended to use get_query_var() after proper registration for better integration and security.

<?php
// Accessing a variable directly from $_GET
if ( isset( $_GET['my_param'] ) ) {
    $my_param_value = sanitize_text_field( wp_unslash( $_GET['my_param'] ) );
    echo '<p>Directly accessed param: ' . esc_html( $my_param_value ) . '</p>';
}
?>

Directly accessing $_GET with basic sanitization.