8.9.1 Problem
8.9.2 Solution
$vars = array('name' => 'Oscar the Grouch',
'color' => 'green',
'favorite_punctuation' => '#');
$safe_vars = array( );
foreach ($vars as $name => $value) {
$safe_vars[ ] = urlencode($name).'='.urlencode($value);
}
$url = '/muppet/select.php?' . join('&',$safe_vars);
8.9.3 Discussion
The URL built in the solution is:
/muppet/select.php?name=Oscar+the+Grouch&color=green&favorite_punctuation=%23
The query string has spaces encoded as +. Special
characters such as # are hex-encoded as %23 because the ASCII
value of # is 35, which is 23 in hexadecimal.
Although urlencode( ) prevents any special characters
in the variable names or values from disrupting the constructed URL, you may
have problems if your variable names begin with the names of HTML entities. Consider this partial URL for retrieving
information about a stereo system:
/stereo.php?speakers=12&cdplayer=52&=10
/stereo.php?speakers=12&cdplayer=52&=10
To prevent embedded entities from corrupting your URLs, you
have three choices. The first is to choose variable names that can't be confused
with entities, such as _amp instead of amp. The second is to
convert characters with HTML entity equivalents to those entities before
printing out the URL. Use htmlentities( ) :
$url = '/muppet/select.php?' . htmlentities(join('&',$safe_vars));
The resulting URL is:
/muppet/select.php?name=Oscar+the+Grouch&color=green&favorite_punctuation=%23
Your third choice is to change the argument separator from
& to ; by setting the configuration directive
arg_separator.input to ;. You then join name-value pairs with
; to produce a query string:
/muppet/select.php?name=Oscar+the+Grouch;color=green;favorite_punctuation=%23
You may run into trouble with any GET method URLs that you
can't explicitly construct with semicolons, such as a form with its method set
to GET, because your users' browsers use & as the argument
separator.
Because many browsers don't support using ; as an
argument separator, the easiest way to avoid problems with entities in URLs is
to choose variable names that don't overlap with entity names. If you don't have
complete control over variable names, however, use htmlentities( ) to
protect your URLs from entity decoding.