Ебись оно конем! или хранение сессий PHP в базе данных MySQL используя PDO.

Поводом для написания этой статьи явилось отсутствие готовых нормальных решений хранения php сессий в базе данных MySQL используя PDO.

Данный пример не предполагает использование стандартного механизма работы с session и переменной $_SESSION. Вместо этого перепишем всё с нуля. Дажее будем работать с объектом $_SESS, так же как с массивом $_SESSION.

Код на php

Настройки
$mysqlhost = "";
$mysqluser = "";
$mysqlpassword = "";
$mysqldb = "";

// Функция для учёта разницы во времени с Моcквой
function mytime() {
return time() + (3600 * 3);
}

// Необходимые функции и объекты
$pdo = new PDO("mysql:host=$mysqlhost;dbname=$mysqldb",$mysqluser,$mysqlpassword,array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
$pdo->exec("SET NAMES UTF-8");
$pdo->exec("SET CHARACTER SET UTF-8");


// Функция генерации ключа для сессии
function gensessid() {
return substr(md5(\"OGO\" . (microtime(true)+8004-mt_rand(0,19000)) . \"RRog!\"),9,22) . substr(md5(\"js8f9\" . (microtime(true)/100-404+mt_rand(0,19000)) . \"oopER4f\"),3,22);
}

class SESS implements ArrayAccess {
protected $_container = array();
protected $update = false; // требуется ли обновить в базе информацию о сессии после завершения работы скрипта
protected $session = \"\";
protected $sessionisset = false;

protected function newsessioncreate() {
global $pdo;
do {
$this->session = gensessid();
$result = $pdo->prepare("SELECT * FROM `sessions` WHERE `id` = :session");
$result->execute(array(\"session\"=>$this->session));
$all = $result->fetchAll();
} while (count($all));
setcookie (\"session\", $this->session,mytime()+157939200);
$this->update = true;
return true;
}

// конструктор
public function __construct($array = null) {
if (!is_null($array)) {
$this->_container = $array;
}
global $pdo;
$this->session = false;
if (isset($_COOKIE[\"session\"])) {
$this->session = $_COOKIE[\"session\"];
$result = $pdo->prepare(\"SELECT * FROM `sessions` WHERE `id` = :session\");
$result->execute(array(\"session\"=>$this->session));
$all = $result->fetchAll();
if (count($all)) {
$this->sessionisset = true;
foreach (json_decode($all[0][\"data\"]) as $key => $value) {
$this->_container[$key] = $value;
}
} else {
$this->newsessioncreate();
}
} else {
$this->newsessioncreate();
}

}

// деструктор
function __destruct() {
global $pdo;
if ($this->update) {
if ($this->sessionisset) {
$result = $pdo->prepare(\"UPDATE `sessions` SET `data` = :data, `updatetime` = :time WHERE `id` = :session\");
$result->execute(array(\"session\"=>$this->session,\"data\"=>json_encode($this->_container),\"time\"=>mytime()));
} else {
$result = $pdo->prepare("INSERT INTO `sessions` SET `id` = :session, `data` = :data, `createtime` = :time\");
$result->execute(array("session"=>$this->session,\"data"=>json_encode($this->_container),"time"=>mytime()));
}
}
return true;
}

// Существует ли элемент
public function offsetExists($offset) {
return isset($this->_container[$offset]);
}
// Получение значения
public function offsetGet($offset) {
return $this->offsetExists($offset) ? $this->_container[$offset] : null;
}
// Установка значения
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->_container[] = $value;
$this->update = true;
} else {
if (!(isset($this->_container[$offset]) and ($this->_container[$offset] == $value))) {
$this->_container[$offset] = $value;
$this->update = true;
}
}
}
// Уничтожение значения
public function offsetUnset($offset) {
unset($this->_container[$offset]);
$this->update = true;
}
}


// Открываем сессию, запуская конструктор объекта SESS

$SESS = new SESS;

Как использовать

Пишите в переменную $_SESS то что хотите сохранить в сесии. Например $_SESS["b"] = 2; Обратиться к переменной можно так $_SESS["b"];

В верху не забудте вписать свои настройки MySQL. Иначе ничего не будет работать.

Авторское право на эту статью принадлежит ресурсу mnogomem, который был не доступен, поэтому статья продублирована на данном сайте. Первоисточник статьи находится по ссылке: http://mnogomem.ru/sessii-php-pdo-v-baze-dannykh-mysql

Вы так же можете прочитать следующие статьи: