2015-10-01 3 views
3
  • Версия Windows: Win 8 64bit
  • WAMP Версия: 2,5 64Bit
  • PHP Версия: 5.5.12

PHP генерирует то, что я d должны описывать как «призрачные» сеансы в таблице сеансов для каждого запроса страницы. Самое странное, что просто щелкнуть по окну браузера, кажется, достаточно, чтобы создать новый сеанс. Это происходит в Firefox и Chrome (никогда не устанавливались расширения/дополнения в Chrome), но в IE11 этого не происходит.PHP Генерация "Ghost" сессий в таблице сессий

На данный момент я понятия не имею, если это ошибка/сбой в том, как Firefox и Chrome обрабатывают файлы cookie или это ошибка в PHP. Код, который я тестирую, ниже (включая SHOW CREATE TABLE для тестовой таблицы).

<?php 
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR); 

$db_type = 'mysql'; 
$db_host = 'local_host'; 

$dsn = 'mysql:dbname=test;host=localhost'; 
$user = 'sess_test_user'; 
$password = 'password'; 

try { 
    $db = new PDO($dsn, $user, $password); 
// Create a new instance of PDO (connect to the database) 
} 
catch(Exception $e) { 
    die('Failed To Connect To Database'); 
} 

class db_session_handler implements SessionHandlerInterface { 

    public function __construct($db) { 
     $this->db = $db; 

    } 

    public function open($save_path,$session_name) { 
     $this->db; 
     return true; 
    } 

    public function close() { 
     unset($this->db); 
     return true; 
    } 

    public function read($session_id) { 

     try { 
      $sql=" 
       SELECT 
        sess_data 
       FROM 
        session_table 
       WHERE 
        sess_id = :sess_id 
      "; 
      $stmt = $this->db->prepare($sql); 
      $stmt->bindParam(':sess_id', $session_id); 
      $stmt->execute(); 
      $res = $stmt->fetchAll(PDO::FETCH_ASSOC); 
      if (count($res) <> 1) { 
       return false; 
      } else { 
       return $res[0]['sess_data']; 
      } 
     } 
     catch (PDOException $e) { 
      return false; 
     } 
    } 

    public function write($session_id,$session_data) {  
     try { 
      $sql=" 
       SELECT 
        sess_data 
       FROM 
        session_table 
       WHERE 
        sess_id = :sess_id 
      "; 
      $stmt = $this->db->prepare($sql); 
      $stmt->bindParam(':sess_id', $session_id); 
      $stmt->execute(); 
      $res = $stmt->fetchAll(PDO::FETCH_ASSOC); 
     } 
     catch (PDOException $e) { 
      return false; 
     } 

     try { 
      if (count($res) === 0) { 
       $sql=" 
       INSERT INTO 
        session_table 
       (
         sess_id 
        , user 
        , start 
        , last_activity 
        , expires 
        , sess_data 
       ) 
       VALUES 
        (
          :sess_id 
         , '0' 
         , NOW() 
         , NOW() 
         , DATE_ADD(NOW(), INTERVAL 30 MINUTE) 
         , :sess_data       
        )    
       "; 
       $stmt->bindParam(':sess_id', $session_id); 
       $stmt->bindParam(':sess_data', $session_data); 
      } else { 
       $sql=" 
        UPDATE 
         session_table 
        SET 
          last_activity = NOW() 
         , expires = DATE_ADD(NOW(), INTERVAL 30 MINUTE) 
         , sess_data = :sess_data 
        WHERE 
         sess_id = :sess_id    
       "; 
      } 
      $stmt = $this->db->prepare($sql); 
      $stmt->bindParam(':sess_id', $session_id); 
      $stmt->bindParam(':sess_data', $session_data); 
      $stmt->execute(); 
      return true; 
     } 
     catch (PDOException $e) { 
      return false; 
     } 
    } 

    public function destroy($session_id) { 
     try { 
      $sql=" 
       DELETE FROM 
        session_table 
       WHERE 
        sess_id = :sess_id 
      "; 
      $stmt = $this->db->prepare($sql); 
      $stmt->bindParam(':sess_id', $session_id); 
      $stmt->execute(); 
      return true; 
     } 
     catch (PDOException $e) { 
      return false; 
     } 
    } 

    public function gc($max_lifetime) { 
     try { 
      $sql=" 
       DELETE FROM 
        session_table 
       WHERE 
        last_activity < expires 
      "; 
      $stmt = $this->db->prepare($sql); 
      $stmt->execute(); 
     } 
     catch (PDOException $e) { 
      return false; 
     } 
    } 

    public function __destruct() { 
     session_write_close(); 
    } 
} 

$db_session_handler = new db_session_handler($db); 
session_set_save_handler($db_session_handler,true); 
session_start(); 

echo session_id(); 

echo " 
CREATE TABLE IF NOT EXISTS `session_table` (
    `sess_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
    `user` int(11) NOT NULL, 
    `start` datetime NOT NULL, 
    `last_activity` datetime NOT NULL, 
    `expires` datetime NOT NULL, 
    `sess_data` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`sess_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 
";  
?> 
+0

99% времени это результат вашего cookie сеанса не принимается. – tadman

+0

Просто опустошил таблицу сеансов (после включения компьютера), запустил тестовый скрипт, firebug показал, что куки-файл, который был отправлен, тестовый скрипт, не повторял никакого cookie-файла. В таблице сеанса были созданы две записи: одна с идентификатором сеанса, который был в отправленном cookie. Обновил тестовый скрипт, и он повторил идентификатор сеанса из файла cookie, но еще одна запись была создана в таблице сеанса. – SpacePhoenix

+0

Прокомментировал использование обработчика сеанса базы данных и открыл папку, в которой хранятся сеансы wamp. Похоже, что это возможно что-то связано с PHPMyAdmin, поскольку, похоже, создается новый сеанс для каждого запроса на страницу. Я использую PHPMyAdmin для взаимодействия с mysql. Мне интересно, может ли быть ошибка в PHPMyAdmin, и когда я храню сеансы в базе данных, возможно, что-то конфликтует где-то – SpacePhoenix

ответ

0

Похоже, FireFox и Chrome были виновниками, после полного их удаления затем переустановить их проблема ушла так, вероятно, что-то в каждый из них получил повреждения в какой-то момент

+0

Обновление: ни перезагрузка, ни повторная установка не работали. Пробовал на компьютере с Windows 7 и никаких проблем, на данный момент мне интересно, имеет ли Windows 8 сбой в том, как он обрабатывает файлы cookie сеанса. – SpacePhoenix

+0

Если кто-то еще получает что-то подобное, попробуйте запустить chrome и Firefox в качестве администратора и совместимости режим для окон 7, который (скрещенные пальцы), кажется, вылечил проблему, поэтому, возможно, за кулисами, должно быть, были какие-то проблемы с разрешениями, возможно, что-то обрабатывается по-разному между окнами 7 и окнами 8 – SpacePhoenix