[php] Beautiful way to remove GET-variables with PHP?

I have a string with a full URL including GET variables. Which is the best way to remove the GET variables? Is there a nice way to remove just one of them?

This is a code that works but is not very beautiful (I think):

$current_url = explode('?', $current_url);
echo $current_url[0];

The code above just removes all the GET variables. The URL is in my case generated from a CMS so I don't need any information about server variables.

This question is related to php url variables get

The answer is


How about:

preg_replace('/\\?.*/', '', $str)

just use echo'd javascript to rid the URL of any variables with a self-submitting, blank form:

    <?
    if (isset($_GET['your_var'])){
    //blah blah blah code
    echo "<script type='text/javascript'>unsetter();</script>"; 
    ?> 

Then make this javascript function:

    function unsetter() {
    $('<form id = "unset" name = "unset" METHOD="GET"><input type="submit"></form>').appendTo('body');
    $( "#unset" ).submit();
    }

Couldn't you use the server variables to do this?

Or would this work?:

unset($_GET['page']);
$url = $_SERVER['SCRIPT_NAME'] ."?".http_build_query($_GET);

Just a thought.


@list($url) = explode("?", $url, 2);

basename($_SERVER['REQUEST_URI']) returns everything after and including the '?',

In my code sometimes I need only sections, so separate it out so I can get the value of what I need on the fly. Not sure on the performance speed compared to other methods, but it's really useful for me.

$urlprotocol = 'http'; if ($_SERVER["HTTPS"] == "on") {$urlprotocol .= "s";} $urlprotocol .= "://";
$urldomain = $_SERVER["SERVER_NAME"];
$urluri = $_SERVER['REQUEST_URI'];
$urlvars = basename($urluri);
$urlpath = str_replace($urlvars,"",$urluri);

$urlfull = $urlprotocol . $urldomain . $urlpath . $urlvars;

You can use the server variables for this, for example $_SERVER['REQUEST_URI'], or even better: $_SERVER['PHP_SELF'].


If the URL that you are trying to remove the query string from is the current URL of the PHP script, you can use one of the previously mentioned methods. If you just have a string variable with a URL in it and you want to strip off everything past the '?' you can do:

$pos = strpos($url, "?");
$url = substr($url, 0, $pos);

How about a function to rewrite the query string by looping through the $_GET array

! Rough outline of a suitable function

function query_string_exclude($exclude, $subject = $_GET, $array_prefix=''){
   $query_params = array;
   foreach($subject as $key=>$var){
      if(!in_array($key,$exclude)){
         if(is_array($var)){ //recursive call into sub array
            $query_params[]  = query_string_exclude($exclude, $var, $array_prefix.'['.$key.']');
         }else{
            $query_params[] = (!empty($array_prefix)?$array_prefix.'['.$key.']':$key).'='.$var;
         }
      }
   }

   return implode('&',$query_params);
}

Something like this would be good to keep handy for pagination links etc.

<a href="?p=3&<?= query_string_exclude(array('p')) ?>" title="Click for page 3">Page 3</a>

Another solution... I find this function more elegant, it will also remove the trailing '?' if the key to remove is the only one in the query string.

/**
 * Remove a query string parameter from an URL.
 *
 * @param string $url
 * @param string $varname
 *
 * @return string
 */
function removeQueryStringParameter($url, $varname)
{
    $parsedUrl = parse_url($url);
    $query = array();

    if (isset($parsedUrl['query'])) {
        parse_str($parsedUrl['query'], $query);
        unset($query[$varname]);
    }

    $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
    $query = !empty($query) ? '?'. http_build_query($query) : '';

    return $parsedUrl['scheme']. '://'. $parsedUrl['host']. $path. $query;
}

Tests:

$urls = array(
    'http://www.example.com?test=test',
    'http://www.example.com?bar=foo&test=test2&foo2=dooh',
    'http://www.example.com',
    'http://www.example.com?foo=bar',
    'http://www.example.com/test/no-empty-path/?foo=bar&test=test5',
    'https://www.example.com/test/test.test?test=test6',
);

foreach ($urls as $url) {
    echo $url. '<br/>';
    echo removeQueryStringParameter($url, 'test'). '<br/><br/>';
}

Will output:

http://www.example.com?test=test
http://www.example.com

http://www.example.com?bar=foo&test=test2&foo2=dooh
http://www.example.com?bar=foo&foo2=dooh

http://www.example.com
http://www.example.com

http://www.example.com?foo=bar
http://www.example.com?foo=bar

http://www.example.com/test/no-empty-path/?foo=bar&test=test5
http://www.example.com/test/no-empty-path/?foo=bar

https://www.example.com/test/test.test?test=test6
https://www.example.com/test/test.test

» Run these tests on 3v4l


Inspired by the comment of @MitMaro, I wrote a small benchmark to test the speed of solutions of @Gumbo, @Matt Bridges and @justin the proposal in the question:

function teststrtok($number_of_tests){
    for($i = 0; $i < $number_of_tests; $i++){
      $str = "http://www.example.com?test=test";
      $str = strtok($str,'?');
    }
}
function testexplode($number_of_tests){
    for($i = 0; $i < $number_of_tests; $i++){
      $str = "http://www.example.com?test=test";
      $str = explode('?', $str);
    }
}
function testregexp($number_of_tests){
    for($i = 0; $i < $number_of_tests; $i++){
      $str = "http://www.example.com?test=test";
      preg_replace('/\\?.*/', '', $str);
    }
}
function teststrpos($number_of_tests){
    for($i = 0; $i < $number_of_tests; $i++){
      $str = "http://www.example.com?test=test";
      $qPos = strpos($str, "?");
      $url_without_query_string = substr($str, 0, $qPos);
    }
}

$number_of_runs = 10;
for($runs = 0; $runs < $number_of_runs; $runs++){

  $number_of_tests = 40000;
  $functions = array("strtok", "explode", "regexp", "strpos");
  foreach($functions as $func){
    $starttime = microtime(true);
    call_user_func("test".$func, $number_of_tests);
    echo $func.": ". sprintf("%0.2f",microtime(true) - $starttime).";";
  }
  echo "<br />";
}
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;

Result: @justin's strtok is the fastest.

Note: tested on a local Debian Lenny system with Apache2 and PHP5.


In my opinion, the best way would be this:

<? if(isset($_GET['i'])){unset($_GET['i']); header('location:/');} ?>

It checks if there is an 'i' GET parameter, and removes it if there is.


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to url

What is the difference between URL parameters and query strings? Allow Access-Control-Allow-Origin header using HTML5 fetch API File URL "Not allowed to load local resource" in the Internet Browser Slack URL to open a channel from browser Getting absolute URLs using ASP.NET Core How do I load an HTTP URL with App Transport Security enabled in iOS 9? Adding form action in html in laravel React-router urls don't work when refreshing or writing manually URL for public Amazon S3 bucket How can I append a query parameter to an existing URL?

Examples related to variables

When to create variables (memory management) How to print a Groovy variable in Jenkins? What does ${} (dollar sign and curly braces) mean in a string in Javascript? How to access global variables How to initialize a variable of date type in java? How to define a variable in a Dockerfile? Why does foo = filter(...) return a <filter object>, not a list? How can I pass variable to ansible playbook in the command line? How do I use this JavaScript variable in HTML? Static vs class functions/variables in Swift classes?

Examples related to get

Getting "TypeError: failed to fetch" when the request hasn't actually failed java, get set methods For Restful API, can GET method use json data? Swift GET request with parameters Sending a JSON to server and retrieving a JSON in return, without JQuery Retrofit and GET using parameters Correct way to pass multiple values for same parameter name in GET request How to download HTTP directory with all files and sub-directories as they appear on the online files/folders list? Curl and PHP - how can I pass a json through curl by PUT,POST,GET Making href (anchor tag) request POST instead of GET?