Smart Query Strings

Have you ever had a time when you started out displaying some simple information in a backend, and you wanted to allow simple paging, so you print out the page numbers as links and they have urls like "?page=3." But then, you want to allow them to sort (or more accurately, they request it after the initial bid). Then you start using $_GET variables and crazy query strings to make it all possible. But what if they want to change the page they are on (i.e. get the next ten items in a long list)? The url for that (which is "?page=3") will make them lose all their sorting and other filtering, etc. So how do you manage it without a million variable checks and some crazy PHP to find out what to do if a particular sort is in effect? I've done it with hidden inputs, but it gets crazy and creates unnecessary lines of (albeit, hidden) code. Whilst pondering this conundrum, I came up with a simple PHP function that gets the current string and then changes any passed in variables in the query string (or appends them if they weren't already there). It's actually pretty short, sweet and effective:

function buildQueryString($vars)  
    // turn current query string and changes into arrays  
    parse_str($_SERVER['QUERY_STRING'], $return);  
    parse_str($vars, $new);

    // for each new piece add it to/change it in the array  
    foreach ($new as $key => $value) $return[$key] = $value;

    // return the string with proper encoding for ampersand  
    return http_build_query($return, '', '&');  

To use it, you put it where you want your smart query string to go. For example, for the one that turns to page 3, I would use <a href="?<?php echo buildQueryString('page=3') ?>">3</a> and if the current query string was "page=4&sort=name&dir=down&=approved=true" the outputted query string in the example would be "page=3&sort=name&dir=down&=approved=true." You can pass in multiple arguments, such as buildQueryString('page=3&sort=name') and it will either change those variables if they exist in the current query string, or else append them.