343

What is the "less code needed" way to get parameters from a URL query string which is formatted like the following?

www.mysite.com/category/subcategory?myqueryhash

Output should be: myqueryhash

I am aware of this approach:

www.mysite.com/category/subcategory?q=myquery

<?php
   echo $_GET['q'];  //Output: myquery
?>
jww
  • 83,594
  • 69
  • 338
  • 732
enloz
  • 5,363
  • 9
  • 33
  • 53

11 Answers11

549

$_SERVER['QUERY_STRING'] contains the data that you are looking for.


DOCUMENTATION

tbc
  • 103
  • 1
  • 12
Filip Roséen - refp
  • 58,021
  • 18
  • 139
  • 186
  • 28
    print_r($_SERVER) to find related values –  Dec 12 '11 at 03:58
  • 22
    note: `$_SERVER['QUERY_STRING']` will show `foo=bar2` for query string like `foo=bar1&foo=bar2` – Timo Huovinen May 09 '13 at 13:39
  • 4
    To get a more readable output, you can wrap the `print_r()` statement in `
    ` tags: `echo '
    '.print_r($_SERVER, TRUE).'
    ';`.
    – Amal Murali Mar 21 '14 at 12:08
  • What if I want to get query string from url like http://example.com/category/qstring ? I want to get "qstring" from the url. – RJ Anoop May 09 '14 at 12:17
  • 1
    @RJAnoop In that case, qstring is part of the URL so you can use `$_SERVER['REQUEST_URI']`, although you may want to consider using mod_rewrite to pass that part of the URL as a variable. See http://stackoverflow.com/questions/16388959/url-rewriting-with-php – nullability Jun 10 '14 at 18:12
  • Why does the page say deprecated? – johnny Jun 02 '15 at 20:19
  • 6
    So why is this better than using $_GET? – still_dreaming_1 Aug 01 '17 at 23:30
  • 2
    @still_dreaming_1: Because the parameter he wants to extract has no name (if I interpret the OP correctly). – Sz. Dec 21 '17 at 16:09
  • 1
    @TimoHuovinen I cannot reproduce that. `$_SERVER['QUERY_STRING']` returns `foo=bar1&foo=bar2` in my case. – fishbone Aug 06 '18 at 07:52
  • 1
    @fishbone Confirm that, with query `?a=b&a=b` `$_SERVER['QUERY_STRING']` returns exactly `a=b&a=b`. – Ivan Shatsky Dec 05 '18 at 15:47
111

The PHP way to do it is using the function parse_url, which parses a URL and return its components. Including the query string.

Example:

$url = 'www.mysite.com/category/subcategory?myqueryhash';
echo parse_url($url, PHP_URL_QUERY); # output "myqueryhash"

Full documentation here

medina
  • 7,561
  • 4
  • 20
  • 24
  • 19
    This is actually the best answer based on the question. The other answers only get the *current* URI whereas the question only specifies "from URL". – Chris Harrison Aug 29 '13 at 05:38
93

The function parse_str() automatically reads all query parameters into an array.

For example, if the URL is http://www.example.com/page.php?x=100&y=200, the code

$queries = array();
parse_str($_SERVER['QUERY_STRING'], $queries);

will store parameters into the $queries array ($queries['x']=100, $queries['y']=200).

Look at documentation of parse_str


EDIT

According to the PHP documentation, parse_str() should only be used with a second parameter. Using parse_str($_SERVER['QUERY_STRING']) on this URL will create variables $x and $y, which makes the code vulnerable to attacks such as http://www.example.com/page.php?authenticated=1.

sbrbot
  • 5,075
  • 3
  • 31
  • 63
  • 54
    ..and is an evil, evil function that should not exist. – Zenexer Jul 17 '13 at 02:31
  • 7
    Zenexer can you elaborate your statement a bit more? WHy this is an evil? – sbrbot Aug 03 '13 at 22:40
  • 28
    You should never blindly turn querystring parameters into variables. What do you think happens if someone uses a key that corresponds to a real variable? It's asking for exploits. That's why this feature is highly discouraged. You can set PHP to do this automatically, without calling `parse_str`, but naturally, it's considered a no-no. – Zenexer Aug 04 '13 at 05:16
  • Seems not be working on my server... I'm not getting the query string variables... – Kamran Ahmed Sep 10 '13 at 04:50
  • 43
    You can use the second parameter of parse_str(). -- `parse_str($_SERVER['QUERY_STRING'], $params);` -- now `$params` array will contain all the query string values. – Amal Murali Oct 20 '13 at 05:24
  • @AmalMurali :Great.Exact what I was looking for. Thanks – pinku Mar 21 '14 at 04:51
  • 1
    I agree @Zenexer this function could be dangerous if not used properly (meaning that one should have array of allowed variables and check this mapping if variables are within alloed list). Contrary to that like any other unwanted PHP function, it can be disabled in php.ini conf file. – sbrbot Jun 23 '15 at 12:25
  • @sbrbot To do that safely, you'd have to parse it yourself. Testing its safety with one parser and then relying on another parser (this function) to actually set the variables provides a false sense of security and is completely pointless. You also might not want to disable it; as Amal Murali pointed out, it has legitimate uses if a second parameter is passed. Generally, you should never import dirty data into the variable space. – Zenexer Jun 30 '15 at 20:42
  • 15
    "You should never blindly turn querystring parameters into variables" Such statements are totally absurd. "Never" -> how do you know what kind of situations any given coder will experience on a random hour of a random workday........ Absolute nonsense. There is no such word as 'never'. ANYTHING is dangerous when you use it wrong, ANYTHING is useful when you use it right....... 10 years ago a lot of people were talking like that regarding IFRAMEs. evil, absolute stupidity. absolute security risk. then came facebook, then came social, iframes everywhere and noone is talking like that now.... – unity100 Sep 27 '15 at 21:34
  • Next to the security issues, you are also missing out most modern IDE's ability to do parameter checks. The parse_str automagically creates the parameters and the IDE will not see it initiated and flag is as undefined. – AFS Aug 04 '17 at 12:18
  • 2
    *"Warning: Using this function **without the second** parameter is highly DISCOURAGED and DEPRECATED as of PHP 7.2."* https://www.php.net/manual/en/function.parse-str.php – sdlins Jan 01 '20 at 19:12
45

If you want the whole query string:

$_SERVER["QUERY_STRING"]
Jason T Featheringham
  • 3,188
  • 23
  • 32
28

I will recommended best answer as

<?php echo 'Hello ' . htmlspecialchars($_GET["name"]) . '!'; ?>

Assuming the user entered http://example.com/?name=Hannes

The above example will output:

Hello Hannes!

user3816325
  • 471
  • 1
  • 6
  • 14
6

This code and notation is not mine. Evan K solves a multi value same name query with a custom function ;) is taken from:

http://php.net/manual/en/function.parse-str.php#76792 Credits go to Evan K.

It bears mentioning that the parse_str builtin does NOT process a query string in the CGI standard way, when it comes to duplicate fields. If multiple fields of the same name exist in a query string, every other web processing language would read them into an array, but PHP silently overwrites them:

<?php
# silently fails to handle multiple values
parse_str('foo=1&foo=2&foo=3');

# the above produces:
$foo = array('foo' => '3');
?>

Instead, PHP uses a non-standards compliant practice of including brackets in fieldnames to achieve the same effect.

<?php
# bizarre php-specific behavior
parse_str('foo[]=1&foo[]=2&foo[]=3');

# the above produces:
$foo = array('foo' => array('1', '2', '3') );
?>

This can be confusing for anyone who's used to the CGI standard, so keep it in mind. As an alternative, I use a "proper" querystring parser function:

<?php
function proper_parse_str($str) {
  # result array
  $arr = array();

  # split on outer delimiter
  $pairs = explode('&', $str);

  # loop through each pair
  foreach ($pairs as $i) {
    # split into name and value
    list($name,$value) = explode('=', $i, 2);
    
    # if name already exists
    if( isset($arr[$name]) ) {
      # stick multiple values into an array
      if( is_array($arr[$name]) ) {
        $arr[$name][] = $value;
      }
      else {
        $arr[$name] = array($arr[$name], $value);
      }
    }
    # otherwise, simply stick it in a scalar
    else {
      $arr[$name] = $value;
    }
  }

  # return result array
  return $arr;
}

$query = proper_parse_str($_SERVER['QUERY_STRING']);
?>
Don't Panic
  • 9,803
  • 5
  • 25
  • 44
aimiliano
  • 970
  • 2
  • 11
  • 18
5

Also if you are looking for current file name along with the query string, you will just need following

basename($_SERVER['REQUEST_URI'])

It would provide you info like following example

file.php?arg1=val&arg2=val

And if you also want full path of file as well starting from root, e.g. /folder/folder2/file.php?arg1=val&arg2=val then just remove basename() function and just use fillowing

$_SERVER['REQUEST_URI']
K. Shahzad
  • 67
  • 1
  • 3
  • 2
    `/` is a valid character in query strings (see [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt)), so you can't rely on `basename`. – Cairnarvon Jan 16 '15 at 01:16
  • 1
    This won't work if the querystring has a slash in it, and is therefore insecure. You're better off obtaining the querystring, removing it from the end of the request URI, _then_ running basename()--then, of course, add the querystring onto the end. – Zenexer Jun 30 '15 at 20:47
4

Here is my function to rebuild parts of the REFERRER's query string.

If the calling page already had a query string in its own URL, and you must go back to that page and want to send back some, not all, of that $_GET vars (e.g. a page number).

Example: Referrer's query string was ?foo=1&bar=2&baz=3 calling refererQueryString( 'foo' , 'baz' ) returns foo=1&baz=3":

function refererQueryString(/* var args */) {

    //Return empty string if no referer or no $_GET vars in referer available:
    if (!isset($_SERVER['HTTP_REFERER']) ||
        empty( $_SERVER['HTTP_REFERER']) ||
        empty(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY ))) {

        return '';
    }

    //Get URL query of referer (something like "threadID=7&page=8")
    $refererQueryString = parse_url(urldecode($_SERVER['HTTP_REFERER']), PHP_URL_QUERY);

    //Which values do you want to extract? (You passed their names as variables.)
    $args = func_get_args();

    //Get '[key=name]' strings out of referer's URL:
    $pairs = explode('&',$refererQueryString);

    //String you will return later:
    $return = '';

    //Analyze retrieved strings and look for the ones of interest:
    foreach ($pairs as $pair) {
        $keyVal = explode('=',$pair);
        $key = &$keyVal[0];
        $val = urlencode($keyVal[1]);
        //If you passed the name as arg, attach current pair to return string:
        if(in_array($key,$args)) {
            $return .= '&'. $key . '=' .$val;
        }
    }

    //Here are your returned 'key=value' pairs glued together with "&":
    return ltrim($return,'&');
}

//If your referer was 'page.php?foo=1&bar=2&baz=3'
//and you want to header() back to 'page.php?foo=1&baz=3'
//(no 'bar', only foo and baz), then apply:

header('Location: page.php?'.refererQueryString('foo','baz'));
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Adriana
  • 91
  • 3
4

Programming Language: PHP

// Inintialize URL to the variable 
$url = 'https://www.youtube.com/watch?v=qnMxsGeDz90'; 

// Use parse_url() function to parse the URL 
// and return an associative array which 
// contains its various components 
$url_components = parse_url($url); 

// Use parse_str() function to parse the 
// string passed via URL 
parse_str($url_components['query'], $params); 

// Display result 
echo 'v parameter value is '.$params['v'];

This worked for me. I hope, it will also help you :)

Kamlesh
  • 2,074
  • 20
  • 19
3

Thanks to @K. Shahzad This helps when you want the rewrited query string without any rewrite additions. Let say you rewrite the /test/?x=y to index.php?q=test&x=y and you want only want the query string.

function get_query_string(){

    $arr = explode("?",$_SERVER['REQUEST_URI']);
    if (count($arr) == 2){
        return "";
    }else{
        return "?".end($arr)."<br>";
    }       
}
$query_string = get_query_string();
Sjaak Wish
  • 185
  • 1
  • 5
2

For getting each node in the URI, you can use function explode() to $_SERVER['REQUEST_URI']. If you want to get strings without knowing if it is passed or not. you may use the function I defined myself to get query parameters from $_REQUEST (as it works both for POST and GET params).

function getv($key, $default = '', $data_type = '')
{
    $param = (isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default);

    if (!is_array($param) && $data_type == 'int') {
        $param = intval($param);
    }

    return $param;
}

There might be some cases when we want to get query parameters converted into Integer type, so I added the third parameter to this function.

Paul Z.
  • 685
  • 1
  • 8
  • 24