# Critique request: PHP cookie library

I've written a fairly small library that abstracts cookie functionality in a way that mimics working with a database model. The repository is on bitbucket and the code is small enough to embed here:

class SimpleCookie {

/**
* @var int
*/
const valueLimit = 2000;

/**
* @var array
*/
protected $cookieData = array(); /** * Cookie name * @var string */ protected$cookieName = null;

/**
*
* @param string $cookieName */ public function __construct($cookieName) {
$this->load($cookieName);
}

/**
* @param string $key * @return mixed */ public function __get($key) {
return
isset($this->cookieData[$key])
? $this->cookieData[$key]
: null;
}

/**
* @param string $key * @param mixed$value
*/
public function __set($key,$value) {
$this->cookieData[$key] = $value; } /** * @param string$key
* @return bool
*/
public function __isset($key) { return isset($this->cookieData[$key]); } /** * @param string$key
*/
public function __unset($key) { if(isset($this->cookieData[$key])) { unset($this->cookieData[$key]); } } /** * Load a cookie * * @param string$cookieName
*/
public function load($cookieName) {$this->setName($cookieName); if(!$data = $this->getCookie($this->cookieName)) {
return false;
}

if(is_array($data)) {$data = implode("", $data); } return$this->setData( $this->getCookieArray($data ) );
}

/**
*
* @param int $expires * @param string$path
* @param string $domain * @param bool$secure
* @param bool $httponly * @return bool */ public function save($expires = 0, $path = "/",$domain = null, $secure = false,$httponly = false) {
$value =$this->getCookieString($this->cookieData);$name  = $this->cookieName; if(strlen($value) > SimpleCookie::valueLimit) {
$value = str_split($value, SimpleCookie::valueLimit);
$result = true; foreach($value as $k =>$v) {
$result =$result && $this->setCookie("{$name}[$k]",$v, $expires,$path, $domain,$secure, $httponly); } return$result;
}

return $this->setCookie($name, $value,$expires, $path,$domain, $secure,$httponly);
}

/**
*
* @since version 0.2
* @param int $expires * @param string$value
* @param string $path * @param string$domain
* @param bool $secure * @param bool$httponly
* @return bool
*/
protected function setCookie($name,$value, $expires = 0,$path = "/", $domain = null,$secure = false, $httponly = false) {$expires  = is_int($expires) || ctype_digit($expires) ? (int) $expires : 0;$path     = is_string($path) ?$path : "/";
$domain = is_string($domain) || is_null($domain) ?$domain : null;
$secure =$secure === true;
$httponly =$httponly === true;

return setcookie($name,$value, $expires,$path, $domain,$secure, $httponly); } /** * Get cookie * * @since version 0.2 * @param string$name
* @return mixed|false
*/
protected function getCookie($name) { return isset($_COOKIE[$name]) && !empty($_COOKIE[$name]) ?$_COOKIE[$name] : false; } /** * Delete a cookie * * @param string$path
* @param string $domain * @param bool$secure
* @param bool $httponly * @return bool */ public function delete($path = "/", $domain = null,$secure = false, $httponly = false) {$this->setData(array());
return $this->save(time() - 3600,$path, $domain,$secure, $httponly); } /** * Get cookie value from array * * Called on save * * @param array$data
* @return string
*/
protected function getCookieString(array $data) { return http_build_query($data);
}

/**
*
*
* @param string $string * @throws InvalidArgumentException * @return array */ protected function getCookieArray($string) {
if(!is_string($string)) { throw new InvalidArgumentException("Cookie string must be a string :)"); } parse_str($string, $data); return$data;
}

/**
*
* This function updates internal data array,
* it does not save the cookie.
*
* @param array $data * @return SimpleCookie */ public function setData(array$data) {
$this->cookieData =$data;

return $this; } /** * Get data array * * @return array */ public function getData() { return$this->cookieData;
}

/**
*
* @param string $cookieName * @throws InvalidArgumentException * @return SimpleCookie */ protected function setName($cookieName) {
if(!is_string($cookieName) || empty($cookieName)) {
throw new InvalidArgumentException("Cookie name must be a non empty string");
}

$this->cookieName =$cookieName;

return \$this;
}
}


I would really love to hear your critiques on:

• Code quality
• Code clarity

I'm more interested in what I'm doing wrong than right. Any opinions on the actual usefulness of the library are welcome, although not central in my question.

Code quality

Well, I did not try your code, but at a first glance it seems to be very robust code. But for further development I would recomend you to set up a test case for your class. See http://www.phpunit.de.

Code clarity

The only part where I got stuck a bit was the save method, but after a second read I got the point. In my opinion any programmer with sufficient oo skills can get your code after one or two reads.

Sometimes you comment, when there is no need for it. Consider the save method: through the methods name it should be clear, that a cookie gets saved. So no need for this comment. Same goes for the constructor, the load, setCookie, getCookie, setData and setName methods. As your code is very readable, I don't see any need for this degree of commenting. I would recomend you just to use the phpdoc comments.

• Bah, there is no such thing as overcommenting if you stick to -why- as opposed to what and how. Nov 13 '11 at 17:57
• Well... Sometimes you do not need to explain why because it should be obvious by reading the code. But I think that's a matter of personal preference.
– mAu
Nov 13 '11 at 18:59