PHP: Хранение сессии в базе данных

PHP: Хранение сессии в базе данных

Как и обещал, тема данной заметки: база данных, как обработчик сессии. А так как на эту тему, умные люди, уже даже придумали шаблоны проектирования… В общем фактически можно делать приложения, жизнь которых не ограничивается временем работы скрипта. Ну, это всё лирика. Вернёмся с небес к коду. Итак…

Как мы помним из предыдущей статьи "PHP: Свои обработчики сессии". Для того что бы приручить механизм сессий в PHP нам нужны шесть callback функций. По сути, задача наша заключается в том, что бы адаптировать эти функции для работы с базой данных. Да… раз уж мы будем работать с базой данных, нам естественно понадобится подопытная таблица, в которой мы и будем хранить сессии.

Создаем таблицу для хранения сессии

 

CREATE TABLE  `baza`.`sessions`

(

  `session_id` VARCHAR( 255 ) NOT NULL COMMENT  'Идентификатор сессии',

  `date_touched` DATETIME NOT NULL COMMENT  'Время доступа к данным',

  `sess_data` TEXT NOT NULL COMMENT  'Данные сессии',

  UNIQUE ( `session_id` )

 

) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

Теперь создадим функционал обработки. Здесь я не стал мудрствовать с PDO, а обошёлся стандартными функциями mysql_ … ведь мне нужно показать, как именно настроить обработчики, а PDO вы, если захотите сможете прикрутить и сами.

 

//Устанавливаем обработчики событиям сессии:

session_set_save_handler( 'sess_open',

                          'sess_close',

                          'sess_read',

                          'sess_write',

                          'sess_destroy',

                          'sess_gb' );

                           

$db = mysql_connect('localhost','root','') or die ('NO CONNECT');

mysql_select_db( 'shop', $db ) or die ('NO SELECT DB');

 

// -----------------------------------------------------------------------

 

// Эти функции оставим пустыми...

function sess_open($sess_path, $sess_name)

{

  return true;

}

function sess_close()

{

  return true;

}

 

// Читаем данные

function sess_read($sess_id)

{

  $sql = 'SELECT

            `sessions`.*

          FROM

            `sessions`

            WHERE

            `session_id` = "'.$sess_id.'"';

   

  $result = mysql_query( $sql )or die( mysql_error().'<br />'.$sql );

   

  $current_time = time();

  // Если данные получены, нам нужно обновить дату

  // доступа к данным:

  if ( mysql_num_rows( $result ) > 0 )

  {

    $row = mysql_fetch_assoc( $result );

     

    $sql = 'UPDATE

              `sessions`

            SET

              date_touched="'.$current_time.'"

            WHERE

              session_id="'.$sess_id.'"';

     

    mysql_query($sql)or die(mysql_error().'<br />'.$sql);

    // Как мы помним только из этого обработчика

    // Мы возвращаем данные, а не логическое значение:

    return html_entity_decode($row['sess_data']);

  }

  else

  {

    $sql = 'INSERT INTO

              `sessions`

            SET

              session_id="'.$sess_id.'",

              date_touched="'.$current_time.'"';

     

     mysql_query($sql)or die(mysql_error().'<br />'.$sql);

      

    return '';

  }

}

 

// Пишем данные:

function sess_write($sess_id, $data)

{

  $current_time = time();

   

  $sql =' UPDATE

            `sessions`

          SET

            `date_touched`='.$current_time.', `sess_data`="'.htmlentities($data,ENT_QUOTES).'"

          WHERE

            `session_id`= "'.$sess_id.'"';

   

  mysql_query($sql)or die(mysql_error().'<br />'.$sql);

   

  return true;

}

 

// Уничтожаем данные:

function sess_destroy($sess_id)

{

  mysql_query('DELETE FROM

                  `sessions`

               WHERE

                  `session_id`="'.$sess_id.'"' )or die(mysql_error());

  return true;

}

 

// Описываем действия сборщика мусора:

function sess_gb($sess_maxlifetime)

{

  $current_time = time();

   

  mysql_query('DELETE FROM

                    `sessions`

               WHERE

                    date_touched + '.$sess_maxlifetime.' < '.$current_time.'')

  or die(mysql_error());

   

  return true;

}

 

//---------------------- Тест работы сессии: ---------------------------------

 

session_start();

 

echo '<h1>'.session_id().'</h1>';

 

// Создадим некий инкремент, если он не существовал,

// И увеличим его на 1, если он существует:

if( isset($_SESSION['increment']) )

{

  $_SESSION['increment']++;

}

else

{

   $_SESSION['increment'] = 1;

}

 

echo '<h1> increment = '.$_SESSION['increment'].'</h1>';

Теперь, если Вы всё сделали правильно, перезагрузите свою страничку — инкремент должен увеличиться на 1, при каждой перезагрузке, а если посмотреть в базу данных, то там мы увидим наши данные. Я думаю теперь "завернуть" весь этот функционал в класс будет не сложно. Можно так же, агрегировать в нём, скажем, объект класса доступа к БД, и ещё объект класса конфигурации, можно добавить так же: удобные методы чтения, записи, удаления данных … что это меня уже понесло в сторону фреймворков. А может это мысли для следующего цикла статей и видеоуроков… 

 

Возможно Вас заинтересуют эти материалы

PHP: Буферизация вывода

Буферизация вывода в PHP это довольно полезная штука, если уметь ею пользоваться. Скажите сколько раз

POP3 протокол с примерами

POP3 это протокол по которому мы можем получить почту с сервера, для подобной задачи, используется

PHP: Свои обработчики сессии

Иногда нам не хватает того, или иного функционала. Когда речь идёт о каком либо классе