Ранее я написал две статьи: «Настройка SESSION (2) — сохранение базы данных» и «Почему я не использую сеанс».
Но позже выяснилось, что были проблемы. Первая обработка на практике практически бесполезна, и перезапуск сеанса приходится обрабатывать отдельно. Последний часто управляет базой данных, вызывая большие проблемы с производительностью.
После тщательного рассмотрения в течение последних двух дней был дан примерный план, но конкретного и подробного испытания не проводилось.
1. Объедините обработку сеанса и статистику. Посетители также фиксируются.
2. Полностью используйте базу данных и файлы cookie для имитации функций сеанса.
3. Операции пользователя в сеансе должны по возможности выполняться одним оператором SQL. Когда сессия не нужна, существует не более одного запроса.
4. В целях эффективности перезапуск сеансов не интегрирован, но предоставляется интерфейс, который можно вызвать для его реализации.
Код приведен временно без подробного пояснения.
sql
СОЗДАТЬ ТАБЛИЦУ `*****_session` (
`sid` char(32) НЕ НУЛЬ,
`uid` int(10) НЕ НУЛЬ,
`username` char(32) NOT NULL,
`usertype` tinyint(1) НЕ NULL,
`activetime` int(10) НЕ НУЛЬ,
`expiry` int(10) NOT NULL,
`ip` char(15) НЕ НУЛЬ,
`url` char(80) НЕ NULL,
`value` char(255) НЕ NULL,
ПЕРВИЧНЫЙ КЛЮЧ («sid»)
) ENGINE=CHARSET ПАМЯТИ ПО УМОЛЧАНИЮ=utf8;
PHP-код
<?
классная сессия {
частный $_sessionPrex= '';//префикс сеанса
Private $_time = '';//текущее время
Private $_model = null // Модель работы базы данных;
Private $_expiry = 1200;//время действия сессии
частный $_domain = '';//область сеанса
protected $isNew = 0;//определить действие операции 0 обновление 1 увеличение
protected $session = array();//соответствующая запись сеанса
публичная функция __construct($options){
$this->_setOptions($options);
if(empty($this->_time))$this->_time = time();
$this->session['activetime'] = $this->_time;
}
публичная функция start(){
$this->_getSid();
}
набор общедоступных функций ($key, $value){
if(in_array($key,array('uid','username','usertype','url','expiry'))){
if($key == 'срок действия'){
$this->_setCookie($this->_sessionPrex.'_sid',$this->session['sid'],$value);
$this->_setCookie($this->_sessionPrex.'_uid',$this->session['uid'],$value);
}
$this->session[$key] = $value;
}еще{
$other = $this->session['value'];
$other[$key] = $value;
$this->session['value'] = $other;
}
}
публичная функция get($key){
if(in_array($key,array('uid','username','usertype','url','expiry'))){
вернуть $this->session[$key];
}еще{
if(isset($this->session['value'][$key])){
вернуть $this->session['value'][$key];
}
вернуть ноль;
}
}
публичная функция gc($file,$time = 1200){
$lasttime = file_get_contents($file);
if($lasttime + $time<$this->_time){
file_put_contents($file,$this->_time);
return $this->_model->delete('activetime+expiry<'.$this->_time);
}
}
публичная функция уничтожить(){
$this->session['uid'] = 0;
$this->session['username'] = '';
$this->session['usertype'] = -1;
$this->session['expiry'] = $this->_expiry;
$this->session['value'] = array();
$this->_setCookie($this->_sessionPrex.'_sid',$this->session['sid'],$this->_expiry);
$this->_setCookie($this->_sessionPrex.'_uid',$this->session['uid'],$this->_expiry);
}
публичная функция __destruct(){
$this->_save();
}
частная функция _save(){
$dbSession = $this->session;
$dbSession['value'] = сериализовать($dbSession['value']);
if(strlen($dbSession['value'])>255)$this->_error('сессия->значение слишком длинное!');
if($this->isNew == 1){
//Увеличивать
$this->_model->insert($dbSession);
}еще{
//обновляем
$sid = $dbSession['sid'];
$this->_model->update(array_slice($dbSession,1),'sid=''.$sid.''');
}
}
частная функция _getSession($sid){
$dbSession = $this->_model->detail('sid = ''.$sid.''');
if(!$dbSession) вернет ложь;
$dbSession['value'] = unserialize($dbSession['value']);
$this->session = array_merge($dbSession,$this->session);
вернуть истину;
}
частная функция _getSid(){
$sid = Strip_tags($_COOKIE[$this->_sessionPrex.'_sid']);
если(strlen($sid)==32){
если ($this->_getSession($sid)){
вернуть истину;
}
}еще{
$sid = md5(time().mt_rand(1000,10000));
$this->_setCookie($this->_sessionPrex.'_sid',$sid);
}
$this->_setCookie($this->_sessionPrex.'_uid',0);
$this->session = массив(
'uid' => 0,
'имя пользователя' => '',
'тип пользователя' => -1,
'activetime' => $this->_time,
'ip' => $this->_getip(),
'url' => Strip_tags($_SERVER['REQUEST_URI']),
'expiry' =>$this->_expiry,
'значение' => массив()
);
$this->isNew = 1;
$this->session['sid'] = $sid;
}
частная функция _setCookie($name,$value,$expiry=0){
if(empty($expiry))$expiry = $this->_expiry;
если (пустой ($this->_domain)){
setcookie($name,$value,$this->_time + $expiry,'/');
}еще{
setcookie($name,$value,$this->_time + $expiry,'/',$this->_domain);
}
}
частная функция _getip(){
вернуть getip();
}
частная функция _setOptions($options){
foreach ($options as $key=>$value){
if(in_array($key,array('sessionPrex','time','model','expiry','domain'))){
$key = '_'.$key;
$this->$key = $value;
}
}
}
частная функция _error($msg){
выбросить новое исключение Phpbean_Exception($msg);
}
}
?>
(Обратите внимание, что этот код нельзя использовать напрямую, эта статья в основном дает представление)