PHP Function: Remove a Query String Key=>Value

By  on  

I was recently coding a website which relied heavily on query string variables. It was absolutely imperative that I keep the query string clean and not duplicate keys. I needed to find a PHP function that would allow me to remove keys (and their values) easily and reliably. Enter a PHP function I found at Added Bytes:

/* the function */
function remove_querystring_var($url, $key) { 
	$url = preg_replace('/(.*)(?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&'); 
	$url = substr($url, 0, -1); 
	return $url; 
}

/* usage */
//pretending this page is 

All I needed to do was provide the URL (in my case I wanted the current page's URI) and the key to remove -- so simple!

All credit goes to Added Bytes for their awesome work. It saved me a lot of time...hopefully it does for you too!

Recent Features

  • By
    Chris Coyier’s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

  • By
    Page Visibility API

    One event that's always been lacking within the document is a signal for when the user is looking at a given tab, or another tab. When does the user switch off our site to look at something else? When do they come back?

Incredible Demos

Discussion

  1. I needed something like this also in a project.
    This is what I came up with

    $qStr = "varOne=1&varTwo=2&key_to_remove=3&varFour=4"; //$_SERVER['QUERY_STRING']
    $key="key_to_remove";
    parse_str($qStr,$ar);
    echo http_build_query(array_diff_key($ar,array($key=>"")));
    //Outputs : varOne=1&varTwo=2&varFour=4
    

    Not sure what’s the performance difference though

  2. I have a very similar function to yours, David, and it seems for nearly the same reason.

    function remove_qs_key($url, $key) {
    	$url = preg_replace('/(?:&|(\?))' . $key . '=[^&]*(?(1)&|)?/i', "$1", $url);
    	return $url;
    }
  3. Amitay

    I would use preg_quote() on the key…

  4. Dutchie

    When do you need to remove a key from a query string? Just curious, since I never needed to and been using php quite long.

  5. Ken Marfilla

    @Phil Pérusse:

    I think unset will be much faster than array_diff if you’re only removing a few keys.

  6. trippo

    Hi,

    I use a similar function sometimes – but it does more than just remove a certain key. The purpose of the function is to build the querystring entirely. It takes two parameters, one array containing keys (with values) that should be added to the querystring and one array containing keys that should be removed. Then it cycles through the current querystring and removes or keeps keys depending on the parameter and finally adds keys if there are any.

    Maybe this approach isn’t as good in your case but I’ve found it to be quite useful when I have a site that’s depending on querystring entirely.

    // trippo

  7. Tiziano Zonta

    the function don’t works if I want to remove first key of my query string

    $query_string = “page=home&lang=it”;
    echo remove_querystring_var($query_string,’page’); //not works
    echo remove_querystring_var($query_string,’lang’); //works

    • Chintan Shah

      Did you get any solution for this ?

    • Hernán

      Same problem. Dadiv’s function is not totally prepared to be use only with a QueryString as parameter. In that case you have to change this line:

      $url = preg_replace('/' . $key . '=[^&]+?(&)(.*)/i', '$4', $url.'&');
      
  8. thanks, that’s cool :)

  9. Hi,

    nice code, but it did not work for the first parameter, because the “?” should be escaped: “\?” to match.
    See here: http://php.net/manual/de/function.preg-replace.php

    if i add escape it works for me:

    function remove_querystring_var($url, $key) { 
    	$url = preg_replace('/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&'); 
    	$url = substr($url, 0, -1); 
    	return $url; 
    }
    
    echo remove_querystring_var("http://www.thinkplexx.com/?errors=%0A%09The+password+field+is+empty.%3B","errors");
    
  10. Still that entire regex could be reduced to:

    preg_replace('/(?:&|(\?))' . $key . '=[^&]*(?(1)&|)?/i', "$1", $url);
    
  11. I like the parse_str/http_query_build idea so I extended it to include the ability to remove an array of values and add an array of values.

    function querystring($strQS, $arRemove, $arAdd = NULL) {
    	parse_str($strQS, $arQS);
    	$arQS = array_diff_key($arQS, array_flip($arRemove));
    	$arQS = $arQS + $arAdd;
    	return http_build_query($arQS);
    }
    

    Example:
    Current URL = http://www.example.com?one=1&two=2&three=3&four=4

    $arR = array('two', 'four');
    $arA = array('five' => 5, 'six' => 6);
    echo querystring($_SERVER['QUERY_STRING'], $arR, $arA);
    prints "one=1&three=3&five=5&six=6"
    
  12. Adam

    @Dustin Hansen: Dustin’s solution is the most elegant and I found the other solutions to have issues with parameter’s at the beginning and end of the query string – in my testing Dustin’s solution worked for parameters at all positions.

  13. Adam

    @Adam: Oh and just for making it even more condensed, shorten the whole function to this:

    function remove_qs_key($url, $key) {
    return preg_replace(‘/(?:&|(\?))’ . $key . ‘=[^&]*(?(1)&|)?/i’, “$1”, $url);
    }

  14. Charlie

    I had an array of checkbox values being passed in the querystring, and I don’t think these functions work for removing it.

    I found it easier to just directly define the $_SERVER['QUERY_STRING'] by concatenating the $_GET[] variables I wanted to pass, and leaving out the ones I didn’t (the checkbox array)

  15. thanks!! lots of cool ways.

    I always like a regular expression but an alternative would be to use the ? as a delimiter and explode the uri into an array and retrieve the first result i.e

    echo reset(explode('?',$_SERVER['REQUEST_URI']));
  16. Tony

    I took the regex and expanded it. PHP allows array references in the querystring vars such as http://www.example.com/?a%5B%5D=1&a%5B0%5D=3&a%5B5%5D%5B7%5D%5B89%5D%5Bfdds%5D%5Bddd%5D=44

    Also, this function allows the removal of multiple vars.


    echo htmlentities(getRedirectURL("http://www.example.com/?a[]=1&a[0]=3&a[5][7][89][fdds][ddd]=44","a"));
    echo htmlentities(getRedirectURL("http://www.example.com/?a=1&a=2&b=3&c=4",array("a","c")));
    function getRedirectURL($url,$keysToRemove) {
    if (!is_array($keysToRemove))
    $keysToRemove = array($keysToRemove);

    foreach ($keysToRemove as $key)
    $url = preg_replace('/(?:&|(\\?|\\G))' . urlencode($key) . '(?:\\[[^]]*\\])*=[^&]*(?(1)&|)?/i', "$1", $url);

    if (substr($url,-1) == '?')
    $url = substr($url,0,-1);

    return $url;
    }

  17. RegEx are Tough to understand… But they solve our problems in short…
    I Use array in such Tasks.

  18. Chintan Shah

    what will be regex, if i want to remove any key from querystring [only] like,
    tab=basic&action=update&tid=57969
    want to delete key like, tab so the result will be ,
    action=update&tid=57969

  19. Chintan Shah

    Above issue is solved by following,
    return preg_replace(‘/’.$key.’=[^&]+?(&)(.*)/i’, ‘$2’, $url);

    But,
    It’s not working for removing last param from url or string, can anyone help for this !!!!

  20. I have two warnings for readers stumble across this article:

    1) Many of the code examples above gave syntax errors when I copied and pasted the code. The syntax errors are caused by this webpage printing a single quotation mark as some other type of symbol that looks similar to a quote mark but is actually not. To solve this, just replace those fake single quote marks with the real thing from your keyboard.

    2) None of the code samples that I tried above worked on the first query parameter in the query string. Even the code samples that say they have this fixed still doesn’t work. (I was getting my Query string from the Server variable. Those who use a full URL might have different results). I believe this is the case because all these code samples look for a ‘&’ symbol to separate query terms. Obviously the first query term will never start with a & symbol.

  21. Adam’s example helped me to resolve a string building issue I was having with pagination of a search facility.

    Beware of the quotes in the examples provided as mentioned by Paul R, many of the examples i tested above required further modification, due to this website’s output.

  22. I recommend using parse_str (if you don’t just use $_GET directly) plus http_build_query. It’s cleaner and closer related to what you really want to do: it’s not the string you care for, it’s the parameters.

    Don’t worry about what solution is the most efficient; that’s microoptimization. The difference is very small compared to the whole request time.

  23. Once the parameter is stripped out, don’t forget to trim any trailing “?” characters from the end. If the parameter being stripped is the only parameter, then a “?” will be left behind, all on its own.

  24. Thanks, David! This helped a lot on an API I was working on.

    Basically, I needed to send an email to myself with the parameters used whenever an error was encountered. Everything was okay, but the server was adding a few of its own parameters to the $_GET variable. I was able to strip it clean with this.

    Thanks again.

  25. parse_str($_SERVER['QUERY_STRING'], $result_array);
    unset($result_array['b']);
    $_SERVER['QUERY_STRING'] = http_build_query($result_array);
  26. function requette_url_remove($url, $key) {
    parse_str($url, $result_array);
    unset($result_array[$key]);
    $url = http_build_query($result_array);
    return $url;
    }

  27. seyi

    Like that solution faisal. Full url solution

    	function remove_querystring_var($url, $key) {
    		$url_parts = parse_url($url);
    		if(empty($url_parts['query'])) return $url;
    		
    		parse_str($url_parts['query'], $result_array);
    		unset($result_array[$key]);
    		$url_parts['query'] = http_build_query($result_array);
    		$url = (isset($url_parts["scheme"])?$url_parts["scheme"]."://":"").
    			(isset($url_parts["user"])?$url_parts["user"].":":"").
    			(isset($url_parts["pass"])?$url_parts["pass"]."@":"").
    			(isset($url_parts["host"])?$url_parts["host"]:"").
    			(isset($url_parts["port"])?":".$url_parts["port"]:"").
    			(isset($url_parts["path"])?$url_parts["path"]:"").
    			(isset($url_parts["query"])?"?".$url_parts["query"]:"").
    			(isset($url_parts["fragment"])?"#".$url_parts["fragment"]:"");
    		return $url;
    	}
    
  28. Kind of the opposite of the article, but you could create allowed array from array_keys(parse_str) and unset the keys you want removed, or modify with a new arg and conditional so it can include or exclude

    /**
     * returns a query string with only the allowed keys
     * 
     * @param  array $allowed array of querystring keys to keep
     * @return string built query string
     */
    function filter_queryString($allowed = array()){
    	parse_str($_SERVER['QUERY_STRING'], $query_string);
    	$qstring_filtered = array_intersect_key($query_string, array_flip($allowed));
    	$new_qstring      = http_build_query($qstring_filtered,'','&');
    	return $new_qstring;
    }
    
  29. Misanthre

    Great article. Another thing to note is that only faisal and seyi’s implementation will remove multiple instances of the given key in the query string. You’ve probably got worse problems if you’ve got multiple keys repeated on the same query string, but a nice feature all the same.

  30. Thanks, very useful.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!