Sunday, March 6, 2011

Persistent HTTP GET variables in PHP

Let's say I have some code like this

if(isset($_GET['foo']))
  //do something

if(isset($_GET['bar']))
  //do something else

If a user is at example.com/?foo=abc and clicks on a link to set bar=xyz, I want to easily take them to example.com/?foo=abc&bar=xyz, rather than example.com/?bar=xyz.

I can think of a few very messy ways to do this, but I'm sure there's something cleaner that I don't know about and haven't been able to track down via Google.

From stackoverflow
  • Just set the link that changes bar to xyz to also have foo=abc if foo is already set.

    $link = ($_GET['foo'] == 'abc') ? 'foo=abc&bar=xyz' : 'bar=xyz';
    ?>
    <a href="whatever.php?<?= $link ?>">Click Me</a>
    
  • You would have to render out the links with the proper URL querystring to make that happen. This is a design decision that you would need to make on your end depending on how your system is setup.

    I have some sites that have this issue, and what I do is setup a querystring global variable that sets the current page data the top of the page request.

    Then when I am rendering the page, if I need to make use of the current query string I do something like:

    echo '<a href="myurl.php' . querystring . '&bar=foo';
    

    It's not the cleanest, but it all depends on how your system works.

  • Here's one way....

    //get passed params
    //(you might do some sanitizing at this point)
    $params=$_GET;
    
    //morph the params with new values
    $params['bar']='xyz';
    
    //build new query string
    $query='';
    $sep='?';
    foreach($params as $name=>$value)
    {
        $query.=$sep.$name.'='.urlencode($value);
        $sep='&';
    }
    
    Byron Whitlock : Very nice. Although you could have used http_build_query to build the query. bravo.
  • If you are updating the query string you need ot make sure you don't do something like

    $qs="a=1&b=2";
    $href="$qs&b=4";
    $href contains "a=1&b=2&b=4"
    

    What you really want to do is overwrite the current key if you need to . You can use a function like this. (disclaimer: Off the top of my head, maybe slightly bugged)

     function getUpdateQS($key,$value)
     {
        foreach ($_GET as $k => $v)
        {
       if ($k != $key)
       {
        $qs .= "$k=".urlencode($v)."&"
       }
       else
       {
        $qs .= "$key=".urlencode($value)."&";
       }
      }
      return $qs
     }
    
        <a href="reports.php?<?getupdateqs('name','byron');?">View report</a>
    
  • Save some code and use the built-in http_build_query. I use this wrapper in one of my projects:

    function to_query_string($array) {
        if(is_scalar($array)) $query = trim($array, '? \t\n\r\0\x0B'); // I could split on "&" and "=" do some urlencode-ing here
        else $query = http_build_query($array);
        return '?'.$query;
    }
    

    Also, though it isn't often used, you can have $_GET on the left-hand side of an assignment:

    $_GET['overriden_or_new'] = 'new_value';
    echo '<a href="'.to_query_string($_GET).'">Yeah!</a>';
    

    Other than that, just do what Paul Dixon said.

0 comments:

Post a Comment