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, при каждой перезагрузке, а если посмотреть в базу данных, то там мы увидим наши данные. Я думаю теперь "завернуть" весь этот функционал в класс будет не сложно. Можно так же, агрегировать в нём, скажем, объект класса доступа к БД, и ещё объект класса конфигурации, можно добавить так же: удобные методы чтения, записи, удаления данных ... что это меня уже понесло в сторону фреймворков. А может это мысли для следующего цикла статей и видеоуроков... ?

Добавить комментарий


Защитный код
Обновить



Кто на сайте
Сейчас 44 гостей онлайн