I believe the answer depends on the size of the query string.
Short query strings
For shorter query strings, this may be the best way:
$fs = array(5, 12, 99);
$fs_no_array = implode(',', $fs);
$url = "http://$_SERVER[HTTP_HOST]/?" .
http_build_query(array('c' => 'asdf', 's' => 'jkl')) . '&fs=' . $fs_no_array;
On the other end you do this to get your array back:
$fs = array_map('intval', explode(',', $_GET['fs']));
Quick note about delimiters: A valid reasons to avoid commas is that they are used as delimiters in so many other applications. On the off-chance you may want to parse your URLs in Excel, for example, the commas might make it slightly more difficult. Underscores also would work, but can blend in with the underlining that is standard in web formatting for links. So dashes may actually be a better choice than either commas or underscores.
Long query strings
I came across another possible solution:
$fs_compressed = urlencode(base64_encode(gzcompress($fs_no_array)));
On the other end it can be decompressed by
$fs_decompressed = gzuncompress(base64_decode($_GET['fs']));
$fs = array_map('intval', explode(',', $fs_decompressed));
assuming it’s passed in through GET variable.
$fs = array(7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,52,53,54,61);
$fs_no_array is 84 characters long,
$fs_compressed 84 characters long. The same!
$fs = array(7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,52,53,54,61);
$fs_no_array is 111 characters long,
$fs_compressed 98 characters long.
The savings is only about 10 %. But at greater lengths the savings will increase to beyond 50 %.
If you use Yahoo sites, you notice things like comma separated lists as well as sometimes a series of random looking characters. They may be employing these solutions in the wild already.
Also check out this stack question, which talks in way too much detail about what is allowed in a URI.