Javascript/PHP Cookies, the Javascript code

This is the code for the Javascript portion of this article, to go directly to the PHP code, go Here

Javascript keywords, functions and properties used :

function, var, new, return, for ++, true, if, else, else if, Ternary operation:condition ? if true : if false, Date(), toGMTString(), split(), indexOf(), substring(), RegExp(), setTime(), getTime(), length, document.cookie, window.location.hostname

Javascript Function interface

The function interface

function processCookie (cookieName, func, name, value, days)
  • cookieName [required] - the name of the cookie.
  • func [required] - what processing on the cookie is required, i.e. kill (delete), clear (non-stacked - delete, stacked - remove name/value pair), set (add/update the name/value pair creating cookie if needs be), read (return the value, if present, of the provided named element)
  • name [required] - identifies the name/value pair to be operated on. If the same as cookieName indicates a non-stacked cookie.
  • value [optional] - supplies the data the be associated with the identified named cookie element.
  • days [optional] - in cases where a cookie is created or updated, this sets the period of validity. Defaults to 365 days.
Javascript "Kill" process...

The Kill process

if (func == 'kill' || (cookieName == name && func == 'clear')) {
  document.cookie = cookieName + 
                    '=; expires=-1;' +
                    "path=/; domain=." +
                    window.location.hostname;
  return true;
}
  1. Check to see if the requested function is either kill or, if the cookieName and name, path and domain parameters are the same and the request function is clear.
  2. Set a cookie of the same name with an expire time in the past. This will replace any existing cookie of the same name and cause the browser to delete the cookie.
Javascript Initialization...

Initialize parameters for remaining processes

var nameQuery = cookieName == name ? name + '=' : name + '-';
var thisCookie = '';
var cookieString = '';
var cookies = document.cookie.split(';');
for (var x = 0; x < cookies.length; x++) {
  if (cookies[x].indexOf(cookieName) != -1) {
    thisCookie = cookies[x].substring(cookies[x].indexOf('=') + 1);
    thisCookie = URLDecode(thisCookie);
  }
}
  • nameQuery is used for searching for the required named value. If the cookie is a stacked cookie, the name/value separator is a "-", if non-stacked, "=". This makes searching for the required string in different places easier.
  • thisCookie is used to contain the targetted cookie, if it exists.
  • cookieString is used to contain data that will eventually be written to a cookie.
  • cookies is an array of strings, each of which is a separate cookie. Javascript acesses all cookies for a given document through a single string with each cookies separated from each other using the ";" symbol.
  • The for loop is used to cycle through existing cookies to find the required cookie string.
  • As PHP will URL encode the value of a given cookie, we must URLDecode the packed value of our cookie. During the PHP URL encoding, the "|" character we use for name/value pair separation is encoded to %7C.
Javascript "Clear" and "Set" process...

The Clear and Set process

if (func == 'clear' || func == 'set') {
  if (func == 'clear') {
    ...
  } else if (func=='set') {
    ...
  }
  var expires = '';
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = '; expires=' + date.toGMTString();
  }
  document.cookie = cookieName + 
                    '=' +
                    URLEncode(cookieString) +
                    expires +
                    '; path=/; domain=.' +
                    window.location.hostname;
  return true;
}

This if/else structure is used to consolidate the expiry and document cookie setting process required by the clear and set processes.

The actual clear and set processing, shown following this, exist in place of the ellipses in the code shown above.

To be compatible with PHP's URL encoding of the each cookie value, our name/value pairs string must be URLEncoded()'d as well.

Javascript "Clear" process...

The Clear process

var myregexp = new RegExp('(\\|' + nameQuery + '[\\w]*|' +
                           nameQuery + '[\\w]*\\||' +
                           nameQuery + '[\\w]*)');
cookieString = thisCookie.replace(myregexp, '');
  1. Construct a regular expression object to search for |name-value, if the name/value pair is at the end of the list, name-value|, if it is in the middle of the list or name-value if it is the only name/value pair.
  2. Use String.replace to execute the regex on thisCookie.
Javascript "Set" process...

The Set process

if (cookieName == name || thisCookie == '') {
  cookieString = nameQuery + value;
} else {
  var myregexp = new RegExp('(' + nameQuery + '[\\w]*)');
  var match = myregexp.exec(thisCookie);
  if (match != null && match.length > 1 && match[1] != '')
    cookieString = thisCookie.replace(match[1], nameQuery + value);
  else
    cookieString = thisCookie + 
                   (thisCookie != '' ? '|' : '') + 
                   nameQuery + value;
}
  1. Check to see if we are dealing with a regular cookie or a stacked but empty cookie and if so, simply set the name/value pair
  2. Create a regex to search for an existing value for the given name.
  3. Execute the regex.
  4. If there is a match, replace it with the new name/value pair.
  5. If there is no match, the name does not currently exist, add the name/value pair with the '|' separator as needed.
Javascript "Read" process...

The Read process

if (func == 'read') {
  if (thisCookie != '') {
    var myregexp = new RegExp(nameQuery + '([\\w]*)');
    var match = myregexp.exec(thisCookie);
    if (match != null && match.length > 1 && match[1] != '')
      return match[1];
  }
  return null;
}
  1. Check to see if there is any cookie data at all, if not, return null.
  2. Construct a regex to search for the value of the requested name/value pair.
  3. Execute the regex and return any matched value.
  4. If nothing matches, return null.
The whole shebang...

The whole shebang

Putting it all together. . .

function processCookie (cookieName, func, name, value, days)@{
  if (func == 'kill' || (cookieName == name && func == 'clear')) {
    document.cookie = cookieName + '=; expires=-86400000';
    return true;
  }

  var nameQuery = cookieName == name ? name + '=' : name + '-';
  var thisCookie = '';
  var cookieString = '';
  var cookies = document.cookie.split(';');
  for (var x = 0; x < cookies.length; x++) {
    if (cookies[x].indexOf(cookieName) != -1)
      thisCookie = cookies[x].substring(cookies[x].indexOf('=') + 1);
      thisCookie = URLDecode(thisCookie);
  }

  if (func == 'clear' || func == 'set') {
    if (func == 'clear') {
      var myregexp = new RegExp('(\\|' + nameQuery + '[\\w]*|' +
                                 nameQuery + '[\\w]*\\||' +
                                 nameQuery + '[\\w]*)');
      cookieString = thisCookie.replace(myregexp, '');
    } else if (func=='set') {
      if (cookieName == name || thisCookie == '')
        cookieString = nameQuery + value;
      else {
        var myregexp = new RegExp('(' + nameQuery + '[\\w]*)');
        var match = myregexp.exec(thisCookie);
        if (match != null && match.length > 1 && match[1] != '')
          cookieString = thisCookie.replace(match[1], nameQuery + value);
        else
          cookieString = thisCookie + 
                         (thisCookie != '' ? '|' : '') + 
                         nameQuery + value;
      }
    }
    var expires = '';
    if (days) {
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      var expires = '; expires=' + date.toGMTString();
    }
    document.cookie = cookieName + 
                      '=' +
                      URLEncode(cookieString) +
                      expires +
                      '; path=/; domain=.' +
                      window.location.hostname;
    return true;
  }

  if (func == 'read') {
    if (thisCookie != '') {
      var myregexp = new RegExp(nameQuery + '([\\w]*)');
      var match = myregexp.exec(thisCookie);
      if (match != null && match.length > 1 && match[1] != '')
        return match[1];
    }
    return null;
  }
}

Continue on with the PHP portion of the code Here