Тема пришла из далекого детства, когда я только начинал программировать, разбирал особенности PHP. На тот момент меня удивляла такая несправедливость: c сессией можно было работать как с обычным ассоциативным массивом($_SESSION), а для кукисов необходимо было использовать функцию setcookie(). Потом я уже поднабрался опыта и понял зачем это сделано именно так.
Время идет и PHP не стоит на месте, в нем появилась такая прекрасная вещь как SPL, одна из возможностей которой — обращение к объекту как к массиву, т.е. реализация ArrayAccess интерфейса.
И вот сейчас я вспомнил о своей детской идее, о массиве $_COOKIE, и реализовал ее:
Реализацию можно посмотреть под катом
Что хорошего в этом решении по сравнению с простой функцией setcookie()? Ну как минимум то, что запись одновременно идет и в браузер и глобальный массив $_COOKIE(иногда приходится работать с ним еще до перезагрузки страницы). В данном варианте есть возможность задать большую часть параметров по умолчанию и регулировать эти параметры. Используя свой класс можно добавить необходимую функциональность в зависимости от конкретных условий.
В любом случае это не универсальное идеальное решение. Это велосипед, да, это мой велосипед. Это идея, которая, возможно, понравится %username% и он ее разовьет до комплексного решения какой-либо задачи.
Время идет и PHP не стоит на месте, в нем появилась такая прекрасная вещь как SPL, одна из возможностей которой — обращение к объекту как к массиву, т.е. реализация ArrayAccess интерфейса.
И вот сейчас я вспомнил о своей детской идее, о массиве $_COOKIE, и реализовал ее:
<?php
/*
достаточно этой строчки чтобы создать куку как на стороне сервера так и клиента
*/
$_COOKIE['lang'] = 'ru';
Реализацию можно посмотреть под катом
<?php
class CookieStorage implements ArrayAccess
{
// сколько по умолчанию будем хранить куки
const DEFAULT_EXPIRE_TIME = 1411200; // 2 недели
// хранилище данных
private $_storage;
// конструктор для записи данных из родного массива $_COOKIE
public function __construct($cookies) {
$this->_storage = $cookies;
}
// стандартный метод ArrayAccess для проверки существования элемента
public function offsetExists ($offset) {
return isset ($this->_storage[$offset]);
}
// стандартный метод ArrayAccess для удаления элемента
public function offsetUnset ($offset) {
unset($this->_storage[$offset]);
}
// метод для получения значение конкретной куки
public function offsetGet ($offset) {
return $this->_storage[$offset];
}
// метод для задания значения куки
public function offsetSet ($offset, $value) {
if( $this->_setCookie($offset, $value) ){
$this->_storage[$offset] = $value;
}
else{
trigger_error('Cookie value was not set', E_USER_WARNING);
}
}
// обертка для функции setcookie
private function _setCookie( $name, $value, $expire = 0, $path = '/', $domain = false, $secure = false , $httponly = false ){
if (!headers_sent()){
if ($domain === false){
$domain = $_SERVER['HTTP_HOST'];
}
if( $expire == 0 ){
$expire = time() + self::DEFAULT_EXPIRE_TIME;
}
return setcookie ( $name, $value, $expire, $path, $domain, $secure, $httponly );
}
return false;
}
}
// инициализация наших кук и переопределение глобального массива
$_COOKIE = new CookieStorage( $_COOKIE );
Что хорошего в этом решении по сравнению с простой функцией setcookie()? Ну как минимум то, что запись одновременно идет и в браузер и глобальный массив $_COOKIE(иногда приходится работать с ним еще до перезагрузки страницы). В данном варианте есть возможность задать большую часть параметров по умолчанию и регулировать эти параметры. Используя свой класс можно добавить необходимую функциональность в зависимости от конкретных условий.
В любом случае это не универсальное идеальное решение. Это велосипед, да, это мой велосипед. Это идея, которая, возможно, понравится %username% и он ее разовьет до комплексного решения какой-либо задачи.