Saturday, December 20, 2008

PHP Cookies - Simple cookie write/read methods that allow basic encryption

Saving and retrieving cookies is extremely simple in PHP using the setcookie() function and $_COOKIE super global variable. But what if you do no want to let the user see the data, let alone alter it? Here is simple cookie write/read methods that allow basic encryption. To delete a cookie, give a negative life


<?php
// Global Cookie Life in seconds, can be overridden in the function call
$cookieLife = 2592000; // 30days

// Global key for encryption, can be overridden in the function call
$encryptKey = '';//'mysecretkey';

/*
@param $name - Name of cookie
@param $val - Value of the cookie
@param $time - Life of the cookie in seconds
@param $key - Key for encrypting cookie
@return TRUE on success else FALSE
*/
function writeCookie($name, $val, $time = null, $key = null){
   
$time = is_null($time) ? $GLOBALS['cookieLife'] : $time;
   
$key = is_null($key) ? $GLOBALS['encryptKey'] : $key;
   
$val = gzcompress(serialize($val) . $key);
   
$val = urlencode(base64_encode($val));

   
// Save the cookie if header is not already sent
   
if(!headers_sent()) {
        return
setcookie($name, $val, time() + $time, '/');
    }else{
        return
FALSE;
    }
}
/*
@param $name - Name of Cookie
@param $key - Key to decrypt, should be same as the one used for encrypting
@param $default - Default value, if the specified cookie does not exist
*/
function readCookie($name, $key = null, $default=null){
    if(isset(
$_COOKIE[$name])){
       
$key = is_null($key) ? $GLOBALS['encryptKey'] : $key;
       
$val = $_COOKIE[$name];
       
$val = base64_decode(urldecode($val));
       
$val = substr(gzuncompress($val), 0, strlen($val) - strlen($key));
       
$val = unserialize($val);
        return
$val;
    }else{
        return
$default;
    }
}
?>




usage example

<?php
// Counter using global key
$counter1 = readCookie('counter1');
$counter1 = is_null($counter1) ? 0 : $counter1;
$str = "Counter 1 - $counter1 (increments by 1)<br/>";
writeCookie('counter1', ++$counter1);

// Counter with key passed during function call
$counter2 = readCookie('counter2', 'mykey');
$counter2 = is_null($counter2) ? 0 : $counter2;
$str .= "Counter 2 - $counter2 (Increments by 2)<br/>";
$counter2 += 2;
writeCookie('counter2', $counter2, null, 'mykey');

// Read cookie, with default value if the specified cookie does not exist
$counter3 = readCookie('counter3', null, 1);
$str .= "Counter 3 - $counter3 (Doubles)<br/>";
$counter3 *= 2;
writeCookie('counter3', $counter3);

echo
$str;

// Invalid Cookie, does not work because output already started at previous line
// If you have output buffering enabled, it will work though
$counter = readCookie('counter', null, 1);
$str .= "Counter Invalid - $counter (Remains 1 always)<br/>";
$counter *= 2;
echo
"Counter Invalid - $counter (Supposed to double, but always shows 2 since header already sent)";
writeCookie('counter', $counter);
?>

No comments: