Uncategorized

Updating PHP cookies without breaking the experience

PHP cookies are a great idea for storing data temporarily. Sure, they have their security problems but (arguably) they do more good than bad. The trickiest part about cookies is when you update your PHP and it forces you to change the contents of your cookies. You don’t want your faithful site visitors to see an error message! Consider the following naive implementation:

function save() {
  setcookie("username","foo",60*60*24*30);
}

function load() {
  return isset($_COOKIE["username"])?$_COOKIE["username"]:'';
}

It doesn’t take a lot of imagination to see how this could break. Let’s start by making it easier to store lots of info in a single cookie.

function save() {
  $data=array('username'=>'foo', 'something else'=>'bar');
  $str=serialize($data);
  setcookie("userdata",$str,60*60*24*30);
}

function load() {
  $data=array('username'=>'','something else'=>'');
  if(isset($_COOKIE['userdata'])) {
     $data=unserialize($_COOKIE['userdata']);
  }
  return $data;
}

Ok, but what about if we need to add more data to our cookies later? Everyone with an old cookie will be missing parts of $data and we’ll have to catch that.

function save() {
  $data=array('version'='1.0', 'username'=>'foo', 'something else'=>'bar');
  $str=serialize($data);
  setcookie("userdata",$str,60*60*24*30);
}

function load() {
  $data=array('username'=>'','something else'=>'');
  $old=false;
  if(isset($_COOKIE['userdata'])) {
    try {
      $data=unserialize($_COOKIE['userdata']);
    }
    catch(Exception $e) {
      $old=true;  // this version is so old & busted we can't read it at all.
    }
    if(!$old) {
      // Use the $data['version'] to help us figure out what pieces of $data need to be filled in.
    }
  }
  return $data;
}

And… voila!