Can a link in WordPress contain a query string that is picked up as $_POST

Looking at the pre_get_posts hook, the problem becomes apparent, the $Format variable is being pulled out of thin air:

function get_all_terms($query) 
{
    if(empty($Format))
      $Format="test 1";

    echo $Format;

This variable is undefined, you cannot declare a variable in one file then use it in in other places like this. To do that you have to declare it as a global variable, and you have to declare this in every place you want to use it.

My recommendation: don’t, there is no need for this variable, take a different approach.

Additionally, there’s a misunderstanding about URLs. WordPress does not know or care what the URL by the time it gets to the pre_get_posts step, and sometimes there is no URL! E.g. in a WP CLI command.

Query variables are just the parameters that WP_Query takes. Rewrite rules convert pretty URLs into lists of query variables, and you can put a query variable in the URL to override most of the time. But query variables isn’t meant to be a representation of what WP thinks the URL is. They can even disagree with the URL!

Instead, if you want to change behaviour based on the URL, just check the URL:

function nora_get_all_terms( \WP_Query $query ) {
    if ( !isset( $_GET['format' ] ) ) {
        return;
    }

Here we check the format URL parameter, and if it is not set, we return early. If it is set, continue the function and use $_GET['format'].

Some notes:

  • get_all_terms is a very generic name, at the very least prefix it or use a more specific name
  • global variables are bad, avoid them
  • Don’t echo out, use a tool such as query monitor to look at the query variables, or better yet, use xdebug + and IDE such as PHPStorm to look at the variables directly with a debugger
  • keep variable names to lowercase, and follow the WP coding standards
  • A decent code editor will automatically indent for you, the codes indenting is broken and this can cause easy mistakes that are impossible when indenting is correct. At a minimum, fix indenting before showing the code to other people as broken indenting makes code difficult to read and understand
  • $_POST and $_GET are populated by PHP, not WordPress. $_POST won’t be populated unless your browser made a POST request
  • Always start with the problem you were trying to solve, don’t fall into the trap of an XY question
  • Consider looking into rewrite rules, you can add a custom query variable, and remove the URL parameter entirely by embedding it in the URL itself with a format/list on the end
  • whitelist and validate the format value, otherwise people can put malicious values in and if the format value is printed anywhere on the page you’ll have a URL injection attack