Pull to refresh

Используем $_COOKIE как $_SESSION

Reading time 2 min
Views 12K
Тема пришла из далекого детства, когда я только начинал программировать, разбирал особенности PHP. На тот момент меня удивляла такая несправедливость: c сессией можно было работать как с обычным ассоциативным массивом($_SESSION), а для кукисов необходимо было использовать функцию setcookie(). Потом я уже поднабрался опыта и понял зачем это сделано именно так.
Время идет и 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% и он ее разовьет до комплексного решения какой-либо задачи.
Tags:
Hubs:
+47
Comments 37
Comments Comments 37

Articles