PHP $_REQUEST array empty

Missing GET request variables are sometimes a symptom of improper rewrite rules in the web-server’s configuration files. In the case of Apache, rewrites are most often implemented using the mod_rewrite module’s directives in the WordPress installation’s directory-level .htaccess configuration file – however, a faulty rewrite rule could also be present in higher-level configuration files (directory, vhost, primary configuration, etc.).

By default, WordPress routes every request for anything except existing files and directories to index.php using a configuration similar to the following:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

There are two modifications that will cause these directives to drop the querystring in the process of rewriting the request:

  • The discard querystring flag. This is added to the square brackets at the end of a RewriteRule directive as either QSD or qsdiscard. If this flag is present for either of the RewriteRule directives in the configuration above, the querystring will be discarded for virtually every request handled by WordPress. For example:

    RewriteRule ^index\.php$ - [L,QSD]
    
  • Any use of a ? in a RewriteRule directive’s substitution string (without the append querystring flag). Specifying any querystring (even a single ? without any subsequent key/value pairs) in the substitution will result in the rewrite completely replacing the original querystring. For example:

    RewriteRule . /index.php? [L]
    

    or

    RewriteRule . /index.php?foo=bar [L]
    

    If it is desireable to append a custom GET variable to every rewrite, the append querystring flag can be specified in the brackets as QSA or qsappend in order to merge the querystring in the substitution with the original querystring instead of completely overwriting it:

    RewriteRule . /index.php?foo=bar [L,QSA]