Manipulate a url string by adding GET parameters

I want to add GET parameters to URLs that may and may not contain GET parameters without repeating ? or &.

Example:

If I want to add category=action

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$url="http://www.acme.com";
// will add ?category=action at the end
$url="http://www.acme.com/movies?sort=popular";
// will add &category=action at the end
</code>
<code>$url="http://www.acme.com"; // will add ?category=action at the end $url="http://www.acme.com/movies?sort=popular"; // will add &category=action at the end </code>
$url="http://www.acme.com";
 // will add ?category=action at the end

$url="http://www.acme.com/movies?sort=popular";
 // will add &category=action at the end

If you notice I’m trying to not repeat the question mark if it’s found.

The URL is just a string.

What is a reliable way to append a specific GET parameter?

1

Basic method

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$query = parse_url($url, PHP_URL_QUERY);
// Returns a string if the URL has parameters or NULL if not
if ($query) {
$url .= '&category=1';
} else {
$url .= '?category=1';
}
</code>
<code>$query = parse_url($url, PHP_URL_QUERY); // Returns a string if the URL has parameters or NULL if not if ($query) { $url .= '&category=1'; } else { $url .= '?category=1'; } </code>
$query = parse_url($url, PHP_URL_QUERY);

// Returns a string if the URL has parameters or NULL if not
if ($query) {
    $url .= '&category=1';
} else {
    $url .= '?category=1';
}

More advanced

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$url = 'http://example.com/search?keyword=test&category=1&tags[]=fun&tags[]=great';
$url_parts = parse_url($url);
// If URL doesn't have a query string.
if (isset($url_parts['query'])) { // Avoid 'Undefined index: query'
parse_str($url_parts['query'], $params);
} else {
$params = array();
}
$params['category'] = 2; // Overwrite if exists
$params['tags'][] = 'cool'; // Allows multiple values
// Note that this will url_encode all values
$url_parts['query'] = http_build_query($params);
// If you have pecl_http
echo http_build_url($url_parts);
// If not
echo $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'] . '?' . $url_parts['query'];
</code>
<code>$url = 'http://example.com/search?keyword=test&category=1&tags[]=fun&tags[]=great'; $url_parts = parse_url($url); // If URL doesn't have a query string. if (isset($url_parts['query'])) { // Avoid 'Undefined index: query' parse_str($url_parts['query'], $params); } else { $params = array(); } $params['category'] = 2; // Overwrite if exists $params['tags'][] = 'cool'; // Allows multiple values // Note that this will url_encode all values $url_parts['query'] = http_build_query($params); // If you have pecl_http echo http_build_url($url_parts); // If not echo $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'] . '?' . $url_parts['query']; </code>
$url = 'http://example.com/search?keyword=test&category=1&tags[]=fun&tags[]=great';

$url_parts = parse_url($url);
// If URL doesn't have a query string.
if (isset($url_parts['query'])) { // Avoid 'Undefined index: query'
    parse_str($url_parts['query'], $params);
} else {
    $params = array();
}

$params['category'] = 2;     // Overwrite if exists
$params['tags'][] = 'cool';  // Allows multiple values

// Note that this will url_encode all values
$url_parts['query'] = http_build_query($params);

// If you have pecl_http
echo http_build_url($url_parts);

// If not
echo $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'] . '?' . $url_parts['query'];

You should put this in a function at least, if not a class.

9

Here’s a shorter version of the accepted answer:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action';
</code>
<code>$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action'; </code>
$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action';

Edit: as discussed in the accepted answer, this is flawed in that it doesn’t check to see if category already exists. A better solution would be to treat the $_GET for what it is – an array – and use functions like in_array().

9

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$data = array('foo'=>'bar',
'baz'=>'boom',
'cow'=>'milk',
'php'=>'hypertext processor');
$queryString = http_build_query($data);
//$queryString = foo=bar&baz=boom&cow=milk&php=hypertext+processor
echo 'http://domain.com?'.$queryString;
//output: http://domain.com?foo=bar&baz=boom&cow=milk&php=hypertext+processor
</code>
<code>$data = array('foo'=>'bar', 'baz'=>'boom', 'cow'=>'milk', 'php'=>'hypertext processor'); $queryString = http_build_query($data); //$queryString = foo=bar&baz=boom&cow=milk&php=hypertext+processor echo 'http://domain.com?'.$queryString; //output: http://domain.com?foo=bar&baz=boom&cow=milk&php=hypertext+processor </code>
$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

$queryString =  http_build_query($data);
//$queryString = foo=bar&baz=boom&cow=milk&php=hypertext+processor

echo 'http://domain.com?'.$queryString;
//output: http://domain.com?foo=bar&baz=boom&cow=milk&php=hypertext+processor

1

Use strpos to detect a ?. Since ? can only appear in the URL at the beginning of a query string, you know if its there get params already exist and you need to add params using &

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>function addGetParamToUrl(&$url, $varName, $value)
{
// is there already an ?
if (strpos($url, "?"))
{
$url .= "&" . $varName . "=" . $value;
}
else
{
$url .= "?" . $varName . "=" . $value;
}
}
</code>
<code>function addGetParamToUrl(&$url, $varName, $value) { // is there already an ? if (strpos($url, "?")) { $url .= "&" . $varName . "=" . $value; } else { $url .= "?" . $varName . "=" . $value; } } </code>
function addGetParamToUrl(&$url, $varName, $value)
{
    // is there already an ?
    if (strpos($url, "?"))
    {
        $url .= "&" . $varName . "=" . $value; 
    }
    else
    {
        $url .= "?" . $varName . "=" . $value;
    }
}

2

This function overwrites an existing argument

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>function addToURL( $key, $value, $url) {
$info = parse_url( $url );
parse_str( $info['query'], $query );
return $info['scheme'] . '://' . $info['host'] . $info['path'] . '?' . http_build_query( $query ? array_merge( $query, array($key => $value ) ) : array( $key => $value ) );
}
</code>
<code>function addToURL( $key, $value, $url) { $info = parse_url( $url ); parse_str( $info['query'], $query ); return $info['scheme'] . '://' . $info['host'] . $info['path'] . '?' . http_build_query( $query ? array_merge( $query, array($key => $value ) ) : array( $key => $value ) ); } </code>
function addToURL( $key, $value, $url) {
    $info = parse_url( $url );
    parse_str( $info['query'], $query );
    return $info['scheme'] . '://' . $info['host'] . $info['path'] . '?' . http_build_query( $query ? array_merge( $query, array($key => $value ) ) : array( $key => $value ) );
}

2

Example with updating existent parameters.

Also url_encode used, and possibility to don’t specify parameter value

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> <?
/**
* Add parameter to URL
* @param string $url
* @param string $key
* @param string $value
* @return string result URL
*/
function addToUrl($url, $key, $value = null) {
$query = parse_url($url, PHP_URL_QUERY);
if ($query) {
parse_str($query, $queryParams);
$queryParams[$key] = $value;
$url = str_replace("?$query", '?' . http_build_query($queryParams), $url);
} else {
$url .= '?' . urlencode($key) . '=' . urlencode($value);
}
return $url;
}
</code>
<code> <? /** * Add parameter to URL * @param string $url * @param string $key * @param string $value * @return string result URL */ function addToUrl($url, $key, $value = null) { $query = parse_url($url, PHP_URL_QUERY); if ($query) { parse_str($query, $queryParams); $queryParams[$key] = $value; $url = str_replace("?$query", '?' . http_build_query($queryParams), $url); } else { $url .= '?' . urlencode($key) . '=' . urlencode($value); } return $url; } </code>
    <?
    /**
     * Add parameter to URL
     * @param string $url
     * @param string $key
     * @param string $value
     * @return string result URL
     */
    function addToUrl($url, $key, $value = null) {
        $query = parse_url($url, PHP_URL_QUERY);
        if ($query) {
            parse_str($query, $queryParams);
            $queryParams[$key] = $value;
            $url = str_replace("?$query", '?' . http_build_query($queryParams), $url);
        } else {
            $url .= '?' . urlencode($key) . '=' . urlencode($value);
        }
        return $url;
    }

One-liner:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$url .= (strpos($url, '?') ? '&' : '?') . http_build_query($additionalParams);
</code>
<code>$url .= (strpos($url, '?') ? '&' : '?') . http_build_query($additionalParams); </code>
$url .= (strpos($url, '?') ? '&' : '?') . http_build_query($additionalParams);

using http_build_query is recommended because it encodes special characters (for example spaces or @ in email addresses)


Improved version for 2022

This allows existing parameters to be replaced, and also preserves existing URL fragment (the part after # at the end of an URL)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>function addParametersToUrl(string $url, array $newParams): string
{
$url = parse_url($url);
parse_str($url['query'] ?? '', $existingParams);
$newQuery = array_merge($existingParams, $newParams);
$newUrl = $url['scheme'] . '://' . $url['host'] . ($url['path'] ?? '');
if ($newQuery) {
$newUrl .= '?' . http_build_query($newQuery);
}
if (isset($url['fragment'])) {
$newUrl .= '#' . $url['fragment'];
}
return $newUrl;
}
</code>
<code>function addParametersToUrl(string $url, array $newParams): string { $url = parse_url($url); parse_str($url['query'] ?? '', $existingParams); $newQuery = array_merge($existingParams, $newParams); $newUrl = $url['scheme'] . '://' . $url['host'] . ($url['path'] ?? ''); if ($newQuery) { $newUrl .= '?' . http_build_query($newQuery); } if (isset($url['fragment'])) { $newUrl .= '#' . $url['fragment']; } return $newUrl; } </code>
function addParametersToUrl(string $url, array $newParams): string
{
    $url = parse_url($url);
    parse_str($url['query'] ?? '', $existingParams);

    $newQuery = array_merge($existingParams, $newParams);

    $newUrl = $url['scheme'] . '://' . $url['host'] . ($url['path'] ?? '');
    if ($newQuery) {
        $newUrl .= '?' . http_build_query($newQuery);
    }

    if (isset($url['fragment'])) {
        $newUrl .= '#' . $url['fragment'];
    }

    return $newUrl;
}

Testing:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$newParams = [
'newKey' => 'newValue',
'existingKey' => 'new',
];
echo addParametersToUrl('https://www.example.com', $newParams);
// https://www.example.com?newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/', $newParams);
// https://www.example.com/dir/?newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/dir/', $newParams);
// https://www.example.com/dir/?newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar', $newParams);
// https://www.example.com/dir/file?foo=bar&newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar&existingKey=old', $newParams);
// https://www.example.com/dir/file?foo=bar&existingKey=new&newKey=newValue
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar&existingKey=old#hash', $newParams);
// https://www.example.com/dir/file?foo=bar&existingKey=new&newKey=newValue#hash
echo addParametersToUrl('https://www.example.com/dir/file#hash', $newParams);
// https://www.example.com/dir/file?newKey=newValue&existingKey=new#hash
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar#hash', $newParams);
// https://www.example.com/dir/file?foo=bar&newKey=newValue&existingKey=new#hash
</code>
<code>$newParams = [ 'newKey' => 'newValue', 'existingKey' => 'new', ]; echo addParametersToUrl('https://www.example.com', $newParams); // https://www.example.com?newKey=newValue&existingKey=new echo addParametersToUrl('https://www.example.com/', $newParams); // https://www.example.com/dir/?newKey=newValue&existingKey=new echo addParametersToUrl('https://www.example.com/dir/', $newParams); // https://www.example.com/dir/?newKey=newValue&existingKey=new echo addParametersToUrl('https://www.example.com/dir/file?foo=bar', $newParams); // https://www.example.com/dir/file?foo=bar&newKey=newValue&existingKey=new echo addParametersToUrl('https://www.example.com/dir/file?foo=bar&existingKey=old', $newParams); // https://www.example.com/dir/file?foo=bar&existingKey=new&newKey=newValue echo addParametersToUrl('https://www.example.com/dir/file?foo=bar&existingKey=old#hash', $newParams); // https://www.example.com/dir/file?foo=bar&existingKey=new&newKey=newValue#hash echo addParametersToUrl('https://www.example.com/dir/file#hash', $newParams); // https://www.example.com/dir/file?newKey=newValue&existingKey=new#hash echo addParametersToUrl('https://www.example.com/dir/file?foo=bar#hash', $newParams); // https://www.example.com/dir/file?foo=bar&newKey=newValue&existingKey=new#hash </code>
$newParams = [
    'newKey' => 'newValue',
    'existingKey' => 'new',
];

echo addParametersToUrl('https://www.example.com', $newParams);
// https://www.example.com?newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/', $newParams);
// https://www.example.com/dir/?newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/dir/', $newParams);
// https://www.example.com/dir/?newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar', $newParams);
// https://www.example.com/dir/file?foo=bar&newKey=newValue&existingKey=new
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar&existingKey=old', $newParams);
// https://www.example.com/dir/file?foo=bar&existingKey=new&newKey=newValue
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar&existingKey=old#hash', $newParams);
// https://www.example.com/dir/file?foo=bar&existingKey=new&newKey=newValue#hash
echo addParametersToUrl('https://www.example.com/dir/file#hash', $newParams);
// https://www.example.com/dir/file?newKey=newValue&existingKey=new#hash
echo addParametersToUrl('https://www.example.com/dir/file?foo=bar#hash', $newParams);
// https://www.example.com/dir/file?foo=bar&newKey=newValue&existingKey=new#hash

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><?php
$url1 = '/test?a=4&b=3';
$url2 = 'www.baidu.com/test?a=4&b=3&try_count=1';
$url3 = 'http://www.baidu.com/test?a=4&b=3&try_count=2';
$url4 = '/test';
function add_or_update_params($url,$key,$value){
$a = parse_url($url);
$query = $a['query'] ? $a['query'] : '';
parse_str($query,$params);
$params[$key] = $value;
$query = http_build_query($params);
$result = '';
if($a['scheme']){
$result .= $a['scheme'] . ':';
}
if($a['host']){
$result .= '//' . $a['host'];
}
if($a['path']){
$result .= $a['path'];
}
if($query){
$result .= '?' . $query;
}
return $result;
}
echo add_or_update_params($url1,'try_count',1);
echo "n";
echo add_or_update_params($url2,'try_count',2);
echo "n";
echo add_or_update_params($url3,'try_count',3);
echo "n";
echo add_or_update_params($url4,'try_count',4);
echo "n";
</code>
<code><?php $url1 = '/test?a=4&b=3'; $url2 = 'www.baidu.com/test?a=4&b=3&try_count=1'; $url3 = 'http://www.baidu.com/test?a=4&b=3&try_count=2'; $url4 = '/test'; function add_or_update_params($url,$key,$value){ $a = parse_url($url); $query = $a['query'] ? $a['query'] : ''; parse_str($query,$params); $params[$key] = $value; $query = http_build_query($params); $result = ''; if($a['scheme']){ $result .= $a['scheme'] . ':'; } if($a['host']){ $result .= '//' . $a['host']; } if($a['path']){ $result .= $a['path']; } if($query){ $result .= '?' . $query; } return $result; } echo add_or_update_params($url1,'try_count',1); echo "n"; echo add_or_update_params($url2,'try_count',2); echo "n"; echo add_or_update_params($url3,'try_count',3); echo "n"; echo add_or_update_params($url4,'try_count',4); echo "n"; </code>
<?php
$url1 = '/test?a=4&b=3';
$url2 = 'www.baidu.com/test?a=4&b=3&try_count=1';
$url3 = 'http://www.baidu.com/test?a=4&b=3&try_count=2';
$url4 = '/test';
function add_or_update_params($url,$key,$value){
    $a = parse_url($url);
    $query = $a['query'] ? $a['query'] : '';
    parse_str($query,$params);
    $params[$key] = $value;
    $query = http_build_query($params);
    $result = '';
    if($a['scheme']){
        $result .= $a['scheme'] . ':';
    }
    if($a['host']){
        $result .= '//' . $a['host'];
    }
    if($a['path']){
        $result .=  $a['path'];
    }
    if($query){
        $result .=  '?' . $query;
    }
    return $result;
}
echo add_or_update_params($url1,'try_count',1);
echo "n";
echo add_or_update_params($url2,'try_count',2);
echo "n";
echo add_or_update_params($url3,'try_count',3);
echo "n";
echo add_or_update_params($url4,'try_count',4);
echo "n";

1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> /**
* @example addParamToUrl('/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
* @example addParamToUrl('//example.com/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
* @example addParamToUrl('https://example.com/path/to/?find=1&FILTER=Y', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
*
* @param $url string url
* @param array $addParams
*
* @return string
*/
function addParamToUrl($url, array $addParams) {
if (!is_array($addParams)) {
return $url;
}
$info = parse_url($url);
$query = array();
if ($info['query']) {
parse_str($info['query'], $query);
}
if (!is_array($query)) {
$query = array();
}
$params = array_merge($query, $addParams);
$result = '';
if ($info['scheme']) {
$result .= $info['scheme'] . ':';
}
if ($info['host']) {
$result .= '//' . $info['host'];
}
if ($info['path']) {
$result .= $info['path'];
}
if ($params) {
$result .= '?' . http_build_query($params);
}
return $result;
}
</code>
<code> /** * @example addParamToUrl('/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS')) * @example addParamToUrl('//example.com/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS')) * @example addParamToUrl('https://example.com/path/to/?find=1&FILTER=Y', array('find' => array('search', 2), 'FILTER' => 'STATUS')) * * @param $url string url * @param array $addParams * * @return string */ function addParamToUrl($url, array $addParams) { if (!is_array($addParams)) { return $url; } $info = parse_url($url); $query = array(); if ($info['query']) { parse_str($info['query'], $query); } if (!is_array($query)) { $query = array(); } $params = array_merge($query, $addParams); $result = ''; if ($info['scheme']) { $result .= $info['scheme'] . ':'; } if ($info['host']) { $result .= '//' . $info['host']; } if ($info['path']) { $result .= $info['path']; } if ($params) { $result .= '?' . http_build_query($params); } return $result; } </code>
 /**
 * @example addParamToUrl('/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
 * @example addParamToUrl('//example.com/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
 * @example addParamToUrl('https://example.com/path/to/?find=1&FILTER=Y', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
 *
 * @param       $url string url
 * @param array $addParams
 *
 * @return string
 */
function addParamToUrl($url, array $addParams) {
  if (!is_array($addParams)) {
    return $url;
  }

  $info = parse_url($url);

  $query = array();

  if ($info['query']) {
    parse_str($info['query'], $query);
  }

  if (!is_array($query)) {
    $query = array();
  }

  $params = array_merge($query, $addParams);

  $result = '';

  if ($info['scheme']) {
    $result .= $info['scheme'] . ':';
  }

  if ($info['host']) {
    $result .= '//' . $info['host'];
  }

  if ($info['path']) {
    $result .= $info['path'];
  }

  if ($params) {
    $result .= '?' . http_build_query($params);
  }

  return $result;
}

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$parameters = array();
foreach ($get as $key => $value)
{
$parameters[] = $key.'='.$value;
}
$url = 'http://example.com/movies?'.implode('&', $parameters);
</code>
<code>$parameters = array(); foreach ($get as $key => $value) { $parameters[] = $key.'='.$value; } $url = 'http://example.com/movies?'.implode('&', $parameters); </code>
$parameters = array();

foreach ($get as $key => $value)
{
     $parameters[] = $key.'='.$value;
}

$url = 'http://example.com/movies?'.implode('&', $parameters);

I think you should do it something like this.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>class myURL {
protected $baseURL, $requestParameters;
public function __construct ($newURL) {
$this->baseurl = $newURL;
$this->requestParameters = array();
}
public function addParameter ($parameter) {
$this->requestParameters[] = $parameter;
}
public function __toString () {
return $this->baseurl.
( count($this->requestParameters) ?
'?'.implode('&', $this->requestParameters) :
''
);
}
}
$url1 = new myURL ('http://www.acme.com');
$url2 = new myURL ('http://www.acme.com');
$url2->addParameter('sort=popular');
$url2->addParameter('category=action');
$url1->addParameter('category=action');
echo $url1."n".$url2;
</code>
<code>class myURL { protected $baseURL, $requestParameters; public function __construct ($newURL) { $this->baseurl = $newURL; $this->requestParameters = array(); } public function addParameter ($parameter) { $this->requestParameters[] = $parameter; } public function __toString () { return $this->baseurl. ( count($this->requestParameters) ? '?'.implode('&', $this->requestParameters) : '' ); } } $url1 = new myURL ('http://www.acme.com'); $url2 = new myURL ('http://www.acme.com'); $url2->addParameter('sort=popular'); $url2->addParameter('category=action'); $url1->addParameter('category=action'); echo $url1."n".$url2; </code>
class myURL {
    protected $baseURL, $requestParameters;

    public function __construct ($newURL) {
        $this->baseurl = $newURL;
        $this->requestParameters = array();
    }

    public function addParameter ($parameter) {
        $this->requestParameters[] = $parameter;
    }

    public function __toString () {
        return $this->baseurl.
               ( count($this->requestParameters) ?
                 '?'.implode('&', $this->requestParameters) :
                 ''
                 );
    }
}

$url1 = new myURL ('http://www.acme.com');
$url2 = new myURL ('http://www.acme.com');
$url2->addParameter('sort=popular');
$url2->addParameter('category=action');
$url1->addParameter('category=action');

echo $url1."n".$url2;

After searching for many resources/answers on this topic, I decided to code my own. Based on @TaylorOtwell’s answer here, this is how I process incoming $_GET request and modify/manipulate each element.

Assuming the url is: http://domain.com/category/page.php?a=b&x=y
And I want only one parameter for sorting: either ?desc=column_name or ?asc=column_name. This way, single url parameter is enough to sort and order simultaneously. So the URL will be http://domain.com/category/page.php?a=b&x=y&desc=column_name on first click of the associated table header row.

Then I have table row headings that I want to sort DESC on my first click, and ASC on the second click of the same heading. (Each first click should “ORDER BY column DESC” first) And if there is no sorting, it will sort by “date then id” by default.

You may improve it further, like you may add cleaning/filtering functions to each $_GET component but the below structure lays the foundation.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>foreach ($_GET AS $KEY => $VALUE){
if ($KEY == 'desc'){
$SORT = $VALUE;
$ORDER = "ORDER BY $VALUE DESC";
$URL_ORDER = $URL_ORDER . "&asc=$VALUE";
} elseif ($KEY == 'asc'){
$SORT = $VALUE;
$ORDER = "ORDER BY $VALUE ASC";
$URL_ORDER = $URL_ORDER . "&desc=$VALUE";
} else {
$URL_ORDER .= "&$KEY=$VALUE";
$URL .= "&$KEY=$VALUE";
}
}
if (!$ORDER){$ORDER = 'ORDER BY date DESC, id DESC';}
if ($URL_ORDER){$URL_ORDER = $_SERVER[SCRIPT_URL] . '?' . trim($URL_ORDER, '&');}
if ($URL){$URL = $_SERVER[SCRIPT_URL] . '?' . trim($URL, '&');}
</code>
<code>foreach ($_GET AS $KEY => $VALUE){ if ($KEY == 'desc'){ $SORT = $VALUE; $ORDER = "ORDER BY $VALUE DESC"; $URL_ORDER = $URL_ORDER . "&asc=$VALUE"; } elseif ($KEY == 'asc'){ $SORT = $VALUE; $ORDER = "ORDER BY $VALUE ASC"; $URL_ORDER = $URL_ORDER . "&desc=$VALUE"; } else { $URL_ORDER .= "&$KEY=$VALUE"; $URL .= "&$KEY=$VALUE"; } } if (!$ORDER){$ORDER = 'ORDER BY date DESC, id DESC';} if ($URL_ORDER){$URL_ORDER = $_SERVER[SCRIPT_URL] . '?' . trim($URL_ORDER, '&');} if ($URL){$URL = $_SERVER[SCRIPT_URL] . '?' . trim($URL, '&');} </code>
foreach ($_GET AS $KEY => $VALUE){
    if ($KEY == 'desc'){
        $SORT = $VALUE;
        $ORDER = "ORDER BY $VALUE DESC";
        $URL_ORDER = $URL_ORDER . "&asc=$VALUE";
    } elseif ($KEY == 'asc'){
        $SORT = $VALUE;
        $ORDER = "ORDER BY $VALUE ASC";
        $URL_ORDER = $URL_ORDER . "&desc=$VALUE";
    } else {
        $URL_ORDER .= "&$KEY=$VALUE";
        $URL .= "&$KEY=$VALUE";
    }
}
if (!$ORDER){$ORDER = 'ORDER BY date DESC, id DESC';}
if ($URL_ORDER){$URL_ORDER = $_SERVER[SCRIPT_URL] . '?' . trim($URL_ORDER, '&');}
if ($URL){$URL = $_SERVER[SCRIPT_URL] . '?' . trim($URL, '&');}

(You may use $_SERVER[SCRIPT_URI] for full URL beginning with http://domain.com)

Then I use resulting $ORDER I get above, in the MySQL query:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>"SELECT * FROM table WHERE limiter = 'any' $ORDER";
</code>
<code>"SELECT * FROM table WHERE limiter = 'any' $ORDER"; </code>
"SELECT * FROM table WHERE limiter = 'any' $ORDER";

Now the function to look at the URL if there is a previous sorting and add sorting (and ordering) parameter to URL with “?” or “&” according to the sequence:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> function sort_order ($_SORT){
global $SORT, $URL_ORDER, $URL;
if ($SORT == $_SORT){
return $URL_ORDER;
} else {
if (strpos($URL, '?') !== false){
return "$URL&desc=$_SORT";
} else {
return "$URL?desc=$_SORT";
}
}
}
</code>
<code> function sort_order ($_SORT){ global $SORT, $URL_ORDER, $URL; if ($SORT == $_SORT){ return $URL_ORDER; } else { if (strpos($URL, '?') !== false){ return "$URL&desc=$_SORT"; } else { return "$URL?desc=$_SORT"; } } } </code>
        function sort_order ($_SORT){
            global $SORT, $URL_ORDER, $URL;
            if ($SORT == $_SORT){
                return $URL_ORDER;
            } else {
                if (strpos($URL, '?') !== false){
                    return "$URL&desc=$_SORT";
                } else {                        
                    return "$URL?desc=$_SORT";
                }
            }
        }

Finally, the table row header to use the function:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> echo "<th><a href='".sort_order('id')."'>ID</a></th>";
</code>
<code> echo "<th><a href='".sort_order('id')."'>ID</a></th>"; </code>
        echo "<th><a href='".sort_order('id')."'>ID</a></th>";

Summary: this will read the URL, modify each of the $_GET components and make the final URL with parameters of your choice with the correct form of usage of “?” and “&”

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> public function addGetParamToUrl($url, $params)
{
foreach ($params as $param) {
if (strpos($url, "?"))
{
$url .= "&" .http_build_query($param);
}
else
{
$url .= "?" .http_build_query($param);
}
}
return $url;
}
</code>
<code> public function addGetParamToUrl($url, $params) { foreach ($params as $param) { if (strpos($url, "?")) { $url .= "&" .http_build_query($param); } else { $url .= "?" .http_build_query($param); } } return $url; } </code>
 public function addGetParamToUrl($url, $params)
{
    foreach ($params as $param) {
         if (strpos($url, "?"))
        {
            $url .= "&" .http_build_query($param); 
        }
        else
        {
            $url .= "?" .http_build_query($param); 
        }
    }
    return $url;
}

another improved function version. Mix of existing answers with small improvements (port support) and bugfixes (checking keys properly).

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>/**
* @param string $url original url to modify - can be relative, partial etc
* @param array $paramsOverride associative array, can be empty
* @return string modified url
*/
protected function overrideUrlQueryParams($url, $paramsOverride){
if (!is_array($paramsOverride)){
return $url;
}
$url_parts = parse_url($url);
if (isset($url_parts['query'])) {
parse_str($url_parts['query'], $params);
} else {
$params = [];
}
$params = array_merge($params, $paramsOverride);
$res = '';
if(isset($url_parts['scheme'])) {
$res .= $url_parts['scheme'] . ':';
}
if(isset($url_parts['host'])) {
$res .= '//' . $url_parts['host'];
}
if(isset($url_parts['port'])) {
$res .= ':' . $url_parts['port'];
}
if (isset($url_parts['path'])) {
$res .= $url_parts['path'];
}
if (count($params) > 0) {
$res .= '?' . http_build_query($params);
}
return $res;
}
</code>
<code>/** * @param string $url original url to modify - can be relative, partial etc * @param array $paramsOverride associative array, can be empty * @return string modified url */ protected function overrideUrlQueryParams($url, $paramsOverride){ if (!is_array($paramsOverride)){ return $url; } $url_parts = parse_url($url); if (isset($url_parts['query'])) { parse_str($url_parts['query'], $params); } else { $params = []; } $params = array_merge($params, $paramsOverride); $res = ''; if(isset($url_parts['scheme'])) { $res .= $url_parts['scheme'] . ':'; } if(isset($url_parts['host'])) { $res .= '//' . $url_parts['host']; } if(isset($url_parts['port'])) { $res .= ':' . $url_parts['port']; } if (isset($url_parts['path'])) { $res .= $url_parts['path']; } if (count($params) > 0) { $res .= '?' . http_build_query($params); } return $res; } </code>
/**
 * @param string $url original url to modify - can be relative, partial etc
 * @param array $paramsOverride associative array, can be empty
 * @return string modified url
 */
protected function overrideUrlQueryParams($url, $paramsOverride){
    if (!is_array($paramsOverride)){
        return $url;
    }

    $url_parts = parse_url($url);

    if (isset($url_parts['query'])) {
        parse_str($url_parts['query'], $params);
    } else {
        $params = [];
    }

    $params = array_merge($params, $paramsOverride);

    $res = '';

    if(isset($url_parts['scheme'])) {
        $res .= $url_parts['scheme'] . ':';
    }

    if(isset($url_parts['host'])) {
        $res .= '//' . $url_parts['host'];
    }

    if(isset($url_parts['port'])) {
        $res .= ':' . $url_parts['port'];
    }

    if (isset($url_parts['path'])) {
        $res .= $url_parts['path'];
    }

    if (count($params) > 0) {
        $res .= '?' . http_build_query($params);
    }

    return $res;
}

Try this function to add URL parameters.

Then you can disable the link when parameter is set so there is no url parameter duplicate.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><?php
function addQueryString($a)
{
if (empty($_SERVER['QUERY_STRING']))
return '?' . $a;
else if (!empty($_SERVER['QUERY_STRING']))
return '?' . $_SERVER['QUERY_STRING'] . '&' . $a;
}
?>
<a href="<?php echo addQueryString('lang=en'); ?>">test</a>
<a href="<?php echo addQueryString('category=5'); ?>">sat</a>
</code>
<code><?php function addQueryString($a) { if (empty($_SERVER['QUERY_STRING'])) return '?' . $a; else if (!empty($_SERVER['QUERY_STRING'])) return '?' . $_SERVER['QUERY_STRING'] . '&' . $a; } ?> <a href="<?php echo addQueryString('lang=en'); ?>">test</a> <a href="<?php echo addQueryString('category=5'); ?>">sat</a> </code>
<?php
  function addQueryString($a)
                {
             if (empty($_SERVER['QUERY_STRING']))
               return '?' . $a;
             else if (!empty($_SERVER['QUERY_STRING']))
              return '?' . $_SERVER['QUERY_STRING'] . '&' . $a;
                }
?>

 <a href="<?php echo addQueryString('lang=en'); ?>">test</a>
 <a href="<?php echo addQueryString('category=5'); ?>">sat</a>

In case you are using WordPress you can simply use

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> add_query_args(['sort' => 'asc'], 'http:/example.com/?search=news')
</code>
<code> add_query_args(['sort' => 'asc'], 'http:/example.com/?search=news') </code>
    add_query_args(['sort' => 'asc'], 'http:/example.com/?search=news')

Docs https://developer.wordpress.org/reference/functions/add_query_arg/

Solution for Laravel

If you are using Laravel you can use a function off of the Request object.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// In a controller function
function foo(Request $request) {
// will be www.laravel.test?hi=there
$urlWithNewQueryParam = $request->fullUrlWithQuery(['hi' => 'there']);
}
// Outside of a controller function (like in a blade)
request()->fullUrlWithQuery(['hi' => 'there']); // will be www.laravel.test?hi=there
</code>
<code>// In a controller function function foo(Request $request) { // will be www.laravel.test?hi=there $urlWithNewQueryParam = $request->fullUrlWithQuery(['hi' => 'there']); } // Outside of a controller function (like in a blade) request()->fullUrlWithQuery(['hi' => 'there']); // will be www.laravel.test?hi=there </code>
// In a controller function
function foo(Request $request) {
    // will be www.laravel.test?hi=there
    $urlWithNewQueryParam = $request->fullUrlWithQuery(['hi' => 'there']);
}

// Outside of a controller function (like in a blade)
request()->fullUrlWithQuery(['hi' => 'there']); // will be www.laravel.test?hi=there

This will also correctly add & and overwrite query params with the same name if they already exist.

You can read more in the docs here https://laravel.com/docs/10.x/requests#retrieving-the-request-url.

Set and remove url query params using PHP:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><?php
function build_url(array $parts): string {
$url = '';
$delimiters = [
'scheme' => [
'value' => '://',
'after' => true
],
'port' => ['value' => ':'],
'query' => ['value' => '?'],
'fragment' => ['value' => '#']
];
foreach ($parts as $name => $part) {
if (isset($delimiters[$name])) {
if (!isset($delimiters[$name]['after'])) {
$url .= $delimiters[$name]['value'] . $part;
} else {
$url .= $part . $delimiters[$name]['value'];
}
} else {
$url .= $part;
}
}
return $url;
}
function set_query_params(array $values, string $url): string {
$parts = parse_url($url);
$params = [];
if (isset($parts['query'])) {
parse_str($parts['query'], $params);
}
$params = array_merge($params, $values);
$parts['query'] = http_build_query($params);
return build_url($parts);
}
function remove_query_params(string | array $name, string $url): string {
$parts = parse_url($url);
if (!isset($parts['query'])) {
throw new Exception('Query not found.');
}
parse_str($parts['query'], $params);
if (is_array($name)) {
if (empty(array_intersect($name, array_keys($params)))) {
throw new Exception('Any params not found.');
}
foreach ($name as $param) {
if (!isset($params[$param])) {
continue;
}
unset($params[$param]);
}
} elseif (!isset($params[$name])) {
throw new Exception("Param with name - $name not found.");
} else {
unset($params[$name]);
}
if (!empty($params)) {
$parts['query'] = http_build_query($params);
} else {
unset($parts['query']);
}
return build_url($parts);
}
$url= set_query_params(['a' => 'b', 'c' => 'd', 'e' => 'f'], 'https://example.com');
echo "$urln"; // output - https://example.com?a=b&c=d&e=f
echo remove_query_params(['a', 'c'], $url) . "n"; // output - https://example.com?e=f
</code>
<code><?php function build_url(array $parts): string { $url = ''; $delimiters = [ 'scheme' => [ 'value' => '://', 'after' => true ], 'port' => ['value' => ':'], 'query' => ['value' => '?'], 'fragment' => ['value' => '#'] ]; foreach ($parts as $name => $part) { if (isset($delimiters[$name])) { if (!isset($delimiters[$name]['after'])) { $url .= $delimiters[$name]['value'] . $part; } else { $url .= $part . $delimiters[$name]['value']; } } else { $url .= $part; } } return $url; } function set_query_params(array $values, string $url): string { $parts = parse_url($url); $params = []; if (isset($parts['query'])) { parse_str($parts['query'], $params); } $params = array_merge($params, $values); $parts['query'] = http_build_query($params); return build_url($parts); } function remove_query_params(string | array $name, string $url): string { $parts = parse_url($url); if (!isset($parts['query'])) { throw new Exception('Query not found.'); } parse_str($parts['query'], $params); if (is_array($name)) { if (empty(array_intersect($name, array_keys($params)))) { throw new Exception('Any params not found.'); } foreach ($name as $param) { if (!isset($params[$param])) { continue; } unset($params[$param]); } } elseif (!isset($params[$name])) { throw new Exception("Param with name - $name not found."); } else { unset($params[$name]); } if (!empty($params)) { $parts['query'] = http_build_query($params); } else { unset($parts['query']); } return build_url($parts); } $url= set_query_params(['a' => 'b', 'c' => 'd', 'e' => 'f'], 'https://example.com'); echo "$urln"; // output - https://example.com?a=b&c=d&e=f echo remove_query_params(['a', 'c'], $url) . "n"; // output - https://example.com?e=f </code>
<?php
function build_url(array $parts): string {
    $url = '';

    $delimiters = [
        'scheme'   => [
            'value' => '://',
            'after' => true
        ],
        'port'     => ['value' => ':'],
        'query'    => ['value' => '?'],
        'fragment' => ['value' => '#']
    ];

    foreach ($parts as $name => $part) {
        if (isset($delimiters[$name])) {
            if (!isset($delimiters[$name]['after'])) {
                $url .= $delimiters[$name]['value'] . $part;
            } else {
                $url .= $part . $delimiters[$name]['value'];
            }
        } else {
            $url .= $part;
        }
    }

    return $url;
}

function set_query_params(array $values, string $url): string {
    $parts = parse_url($url);
    $params = [];
    if (isset($parts['query'])) {
        parse_str($parts['query'], $params);
    }

    $params = array_merge($params, $values);
    $parts['query'] = http_build_query($params);

    return build_url($parts);
}

function remove_query_params(string | array $name, string $url): string {
    $parts = parse_url($url);
    if (!isset($parts['query'])) {
        throw new Exception('Query not found.');
    }
    parse_str($parts['query'], $params);

    if (is_array($name)) {
        if (empty(array_intersect($name, array_keys($params)))) {
            throw new Exception('Any params not found.');
        }

        foreach ($name as $param) {
            if (!isset($params[$param])) {
                continue;
            }

            unset($params[$param]);
        }
    } elseif (!isset($params[$name])) {
        throw new Exception("Param with name - $name not found.");
    } else {
        unset($params[$name]);
    }

    if (!empty($params)) {
        $parts['query'] = http_build_query($params);
    } else {
        unset($parts['query']);
    }

    return build_url($parts);
}

$url= set_query_params(['a' => 'b', 'c' => 'd', 'e' => 'f'], 'https://example.com');
echo "$urln";  // output - https://example.com?a=b&c=d&e=f
echo remove_query_params(['a', 'c'], $url) . "n"; // output - https://example.com?e=f

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật