PHP: Adding Parameters To A URL in PHP

  • Post category:PHP
  • Post comments:0 Comments
PHP: Adding Parameters To A URL in PHP
Adding Parameters To A URL in PHP

This article shows how to add query parameters to a URL in a php script. It is aimed at the beginner to intermediate level PHP programmer but developers from other languages may find some useful information here. At first this seems like a simple enough task. Starting with the url as a string, just add the new parameters to the end. Yeah, that would be nice. It turns out that there are a few conditions that make the process just a bit more difficult. It’s still not a hard problem but there are enough special cases to make it interesting.

The simple case
The simple case is the one I mentioned in the introduction paragraph. We have a simple URL and we want to add a query parameter to it. By a simple URL I mean that there are no other parameters or named anchors after the name. In this case the parameter can be appended to the end of the URL using a “?” to mark the beginning of the parameter list. The following bit of PHP code shows how this would work:

<?php
$url = "http://www.vnoel.com";       // The simple url
$name = "cmd";                       // The parameter name
$value = "list";                     // The parameter value
$newUrl = $url . "?$name=$value";    // appending the values
print($newUrl);                      // prints: http://www.vnoel.com?cmd=list
?>

This is nice and easy but unfortunately this simple case is relatively rare. Let’s now look at some more complicated cases.

Some parameters already exist
The next case we’ll consider is the situation where some parameters already exist in the url. This is probably the most common situation. First let’s look at what happens if we use the same approach as with the simple case.

<?php
$url = "http://www.vnoel.com?cmd=list";  // The simple url
$name = "option";                        // The parameter name
$value = "new";                          // The parameter value
$newUrl = $url . "?$name=$value";        // appending the values
 
// prints:http://www.vnoel.com?cmd=list?option=new
print($newUrl);
?>

Notice that the value that gets printed contains two “?” symbols. The HTTP specification indicates that only the first one counts as a delimiter for separating the parameter list. What happens to the second “?”? It becomes a part of the value for the cmd parameter. That is, the value of the cmd parameter in the script that receives it will be list?option=new. This is probably not what was intended.
The correct way to list multiple parameters in a URL is to separate them with the “&” symbol. The desired URL in our example is http://www.vnoel.com?cmd=list&option=new. So we will adjust the example code to use the “&”.

<?php
$url = "http://www.vnoel.com?cmd=list";  // The simple url
$name = "option";                        // The parameter name
$value = "new";                          // The parameter value
$newUrl = $url . "&$name=$value";        // appending the values
 
// prints:http://www.vnoel.com?cmd=list&option=new
print($newUrl);
?>

This works great as long as the the original URL already has a parameter. If it doesn’t have a parameter then we end up with the wrong URL. So we have to check to see if there are some parameters already.

<?php
$url = "http://www.vnoel.com?cmd=list";  // The simple url
$name = "option";                        // The parameter name
$value = "new";                          // The parameter value
 
$separator = "?";
if (strpos($url,"?")!=false)
  $separator = "&";
 
$newUrl = $url . $separator . "$name=$value";        // appending the values
 
// prints:http://www.vnoel.com?cmd=list&option=new
print($newUrl);
?>

This will work for 95% of the cases you will encounter. Notice that the code selects the correct separator based on the presence of other parameters. If no other parameters exist then it uses “?” otherwise it uses “&”. This allows the code to handle both the simple case and this more complicated situation.

Dealing with named anchors
A named anchor is indicated in the url using the “#” symbol. This directs the browser to jump to a particular location in the served page. The HTTP specification indicates that these must appear at the end of the URL — after all of the parameters. The approach we’ve used so far of adding the new parameter to the end of the URL won’t work when a named anchor is present. Instead we will have to insert the new parameter into the URL before the named anchor. To do this we will use the substr_replace method.

<?php
$url = "http://www.vnoel.com?cmd=list#here";  // The simple url
$name = "option";                        // The parameter name
$value = "new";                          // The parameter value
 
// Pick the correct separator to use
$separator = "?";
if (strpos($url,"?")!==false)
  $separator = "&";
 
// Find the location for the new parameter
$insertPosition = strlen($url); 
if (strpos($url,"#")!==false)
  $insertPosition = strpos($url,"#");
 
// Build the new url
$newUrl = substr_replace($url,"$separator$name=$value",$insertPosition,0);
 
// prints:http://www.vnoel.com?cmd=list&option=new
print($newUrl);
?>

The parameter is already present
The final case to look at is the situation in which the new parameter is already present in the URL with a different value. This case is not so clear cut as the previous ones. The difficulty here is that there are two “correct” answers for dealing with this problem. The desired behavior might be to override the old parameter value with the new value or it might be that the goal is to have both values presented to the script responding to the URL.
Overridding the value is easy. The code we’ve written so far will do that. PHP processes multiple parameters with the same name by using the value of the last instance of that parameter. Since our code is inserting at the end of the URL (accounting for anchors) we know that the new value will override the original value. If the intention is for all values for the parameter to be available to the script then we have to do a bit more magic. When the PHP engine is processing query parameters it treats parameters with a name ending with [] as a special case. For these paramters PHP creates an array and with entries for each value. For example, the URL http://www.vnoel.com/test.php?data[]=bob&data[]=joe&data[]=sue will result in PHP providing an array named data with three elements (bob,joe,sue) to the test.php script.
The code for converting the parameter to an array is fairly straight-forward. We try to replace all instances of the parameter name with the modified name. If any replacements are made then we adjust the name of the parameter to add as well. If we do all of this before inserting the parameter into the URL then we can reuse all of the existing insert code.

<?php
$url = "http://www.vnoel.com?cmd=list#here";  // The simple url
$name = "option";                        // The parameter name
$value = "new";                          // The parameter value
 
// This only applies if parameter arrays are used
$modifiedName = $name . "&#91;&#93;";
$newUrl = str_replace("$name=","$modifiedName=",$url,$numberReplaced);
if ($numberReplaced > 0) {
  $url = $newUrl;
  $name = $modifiedName;
}
 
// Pick the correct separator to use
$separator = "?";
if (strpos($url,"?")!==false)
  $separator = "&";
 
// Find the location for the new parameter
$insertPosition = strlen($url); 
if (strpos($url,"#")!==false)
  $insertPosition = strpos($url,"#");
 
// Build the new url
$newUrl = substr_replace($url,"$separator$name=$value",$insertPosition,0);
 
// prints:http://www.vnoel.com?cmd=list&option=new
print($newUrl);
?>

This approach to handling multiple instances of the same parameter is PHP specific. That is, other languages, do not use the [] notation or assume that the last value assigned wins.
This covers most of the cases that you will encounter when trying to add new parameters to an existing URL. If you find bugs or ommissions in the examples I’ve given here or if you find other cases that I should cover send me an email and I’ll try to adjust the article.