2013-02-24 5 views
0

Я создал этот класс сеанса, используя этот article .. Я действительно уверен, что соблюдал все правила и всю предоставленную информацию, но мой код не работает.Класс сеанса PHP не работает

класс Session: session.php

class Session { 

    function __construct() { 

     // set our custom session functions 
     session_set_save_handler(
      array($this, 'open'), 
      array($this, 'close'), 
      array($this, 'read'), 
      array($this, 'write'), 
      array($this, 'destroy'), 
      array($this, 'gc') 
     ); 

     // This line prevents unexpected effects when using objects as save handlers 
     register_shutdown_function('session_write_close'); 

    } 

    function start_session($session_name, $secure) { 

     // Make sure the session cookie is not accessable via javascript 
     $httponly = true; 

     // Hash algorith to use for the session_id 
     $session_hash = 'sha512'; 

     // Check if hash is available 
     if (in_array($session_hash, hash_algos())) { 

      // Set the hash function 
      ini_set('session.hash_function', $session_hash); 

     } 

     // How many bits per character of the hash 
     ini_set('session.hash_bits_per_character', 5); 

     // Force the session to only use cookies, nut URL variables 
     ini_set('session.use_only_cookies', 1); 

     // Get session cookie parameters 
     $cookieParams = session_get_cookie_params(); 

     // Set the parameters 
     session_set_cookie_params(
      $cookieParams['lifetime'], 
      $cookieParams['path'], 
      $cookieParams['domain'], 
      $secure, 
      $httponly 
     ); 

     // Change the sesion name 
     session_name($session_name); 

     // Now we can start the session 
     session_start(); 

     // This line regenerates the session and delete the old one 
     // It also generates a new encryption key in the database 
     session_regenerate_id(true);  

    } 

    function open() { 

     // Define Connection variables 
     $host = ''; 
     $user = ''; 
     $pass = ''; 
     $dbnm = ''; 

     // Connection string based on connection variables 
     $PDO = new PDO("mysql:host=$host;dbname=$dbnm", $user, $pass); 

     // Connect to DB based on connection string 
     $this->db = $PDO; 
     return true; 

    } 

    function close() { 

     // Close DB connection 
     $this->db->close(); 
     return true; 

    } 

    function read($id) { 

     // If not the read statement is defined 
     if(!isset($this->read_stmt)) { 

      // Prepared statement for getting data from DB 
      $this->read_stmt = $this->db->prepare("SELECT data FROM sessions WHERE id = ? LIMIT 1"); 

     } 

     $this->read_stmt->bind_param('s', $id); // Replace ? with $id 
     $this->read_stmt->execute();    // Execute the prepared statement 
     $this->read_stmt->store_result();   // We store the data returned 
     $this->read_stmt->bind_result($data);  // We bind the result to a $data variable 
     $this->read_stmt->fetch();     // And fetch returned data 

     // This function is defined later 
     // but returns the session key based on the $id 
     $key = $this->getkey($id); 

     // Both the variabels are decrypted and assigned to $data 
     $data = $this->decrypt($data, $key); 

     // We return the results 
     return $data; 

    } 

    function write($id, $data) { 

     // Get unique session key 
     $key = $this->getkey($id); 

     //Encrypt the data 
     $data = $this->encrypt($data); 

     // Assign current time to $time variable 
     $time = time(); 

     // If not the write statement is defined 
     if(!isset($this->write_stmt)) { 

      // Prepared statement for replacing data in DB 
      $this->write_stmt = $this->db->prepare("REPLACE INTO sessions (id, set_time, data, session_key) VALUES (?, ?, ?, ?)"); 

     } 

     $this->write_stmt->bind_param('siss', $id, $time, $data, $key); // Replace ?, ?, ?, ? with $id, $time, $data, $key 
     $this->write_stmt->execute();          // Execute the prepared statement 

     // Return confirmation 
     return true; 

    } 

    function destroy($id) { 

     // If not the delete statement is defined 
     if(!isset($this->delete_stmt)) { 

      // Prepared statement for deleting session data from DB 
      $this->delete_stmt = $this->db->prepare("DELETE FROM sessions WHERE id = ?"); 

     } 

     $this->delete_stmt->bind_param('s', $id); // Replace ? with $id 
     $this->delete_stmt->execute();    // Execute the prepared statement 

     // Return confirmation 
     return true; 

    } 

    function gc($max) { 

     // This function 'Garbage Collector' is emptying the DB for old sessions 
     // this way, the DB takes care of itself. 

     // If not the GC statement is defined 
     if(!isset($this->gc_stmt)) { 

      // Prepared statement for deleting session data from DB 
      $this->gc_stmt = $this->db->prepare("DELETE FROM sessions WHERE set_time < ?"); 

     } 

     // Define $old to be an old statement 
     $old = time() - $max; 

     $this->gc_stmt->bind_param('s', $old); // Replace ? with $old 
     $this->gc_stmt->execute();    // Execute the prepared statement 

     // Return confirmation 
     return true; 

    } 

    private function getkey($id) { 

     // This function is used to get the unique key for encryption from the sessions table. 
     // If there is no session it just returns a new random key for encryption. 

     // If not the select statement is defined 
     if(!isset($this->key_stmt)) { 

      // Prepared statement for selecting session key from DB 
      $this->key_stmt = $this->db->prepare("SELECT session_key FROM sessions WHERE id = ? LIMIT 1"); 

     } 

     $this->key_stmt->bind_param('s', $id); // Replace ? with $old 
     $this->key_stmt->execute();   // Execute the prepared statement 
     $this->key_stmt->store_result();  // We store the data returned 

     // If the select statement returns a row 
     if($this->key_stmt->num_rows == 1) { 

      $this->key_stmt->bind_result($key); // We bind the result to a $data variable 
      $this->read_stmt->fetch();    // And fetch returned data 

      // Then we return the result 
      return $key; 

     } else { 

      // We generate a random key 
      $random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true)); 

      // Then we return the result 
      return $random_key; 

     } 

    } 

    private function encrypt($data, $key) { 

     // A complete random key for encryption 
     $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*[email protected]@pH'; 

     // We assign a hash encoded version of the random key and session key to the $key 
     $key = substr(hash('sha256', $salt.$key.$salt), 0, 32); 

     // Open module, and create IV 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); 
     $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 

     // Do the encryption and assign it to $encrypted 
     $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv)); 

     // And return the encrypted data 
     return $encrypted; 

    } 

    private function decrypt($data, $key) { 

     // The same key for encryption is used for decrytion (obviously) 
     $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*[email protected]@pH'; 

     // We assign a hash encoded version of the random key and session key to the $key 
     $key = substr(hash('sha256', $salt.$key.$salt), 0, 32); 

     // Open module, and create IV 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); 
     $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 

     // Do the decryption and assign it to $decrypted 
     $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv); 

     // And return the decrypted data 
     return $decrypted; 

    } 

} 

А потом у меня есть две страницы для тестирования. Я также верю, что эти страницы написаны правильно, поэтому должно быть что-то, что препятствует работе класса. У меня есть большой скрипт, где я использую тот же класс, и я могу определить новый класс $session = new Session();, но когда я начинаю сеанс $session->start_session('test', false); сценарий умирает.

Тестовая страница PHP: tester.php

<? 
require_once('session.php'); 
$session = new Session(); 

$session->start_session('test', false); 

$_SESSION['dims'] = 'This is a session variable'; 

?> 

<a href="tester2.php">click here</a> 

Тестовая страница 2 PHP: tester2.php

<? 
require_once('session.php'); 
$session = new Session(); 

$session->start_session('test', false); 

echo $_SESSION['dims']; 

?> 

я узнал, что появилась ошибка внутреннего сервера ошибка 500.

+0

Вы регистрировали ошибки? – kirugan

+0

Я пробовал это, но на самом деле никаких ошибок не появилось. – Dimser

+0

Ошибка скважины 500 означает ошибку сервера, если ваш сервер не является необычным, и вы включаете ведение журнала (в вашем коде и в конфигурации сервера), чем вы его увидите. С четким описанием ошибки мы можем помочь намного быстрее. – kirugan

ответ

1

Ваш класс установил соединение через PDO, но в следующем учебном руководстве используются подготовленные операторы MySQLi. Эти два API несовместимы друг с другом. Эквивалентный код в PDO будет выглядеть так:

 // If not the read statement is defined 
    if(!isset($this->read_stmt)) { 

     // Prepared statement for getting data from DB 
     // Prepare using the named parameter :id instead of ? (though ? can be used in PDO too) 
     $this->read_stmt = $this->db->prepare("SELECT data FROM sessions WHERE id = :id LIMIT 1"); 

    } 
    // If the statement was successfully prepared... 
    if ($this->read_stmt) { 
     // One of 2 param binding methods in PDO... 
     $this->read_stmt->bindParam(':id', $id, PDO::PARAM_STR); 
     $this->read_stmt->execute(); 
     // No correlate for store_result() in PDO... 

     // Fetch the first row and get the data key from it 
     // You don't need to do a bind result in PDO. Instead just fetch() or fetchAll() 
     // more like the old mysql_fetch_*() functions. 
     $row = $this->read_stmt->fetch(PDO::FETCH_ASSOC); 
     $data = $row['data'] 

     // Do the rest of your stuff with data. 
    } 

Я не буду переводить весь блок кода выше, но это должно вам начать работу. У PDO docs on bindParam() достаточно примеров того, что вы также сможете выяснить свои другие вопросы.

Наконец, я рекомендую PDO Tutorial for MySQL Developers, который имеет отличные примеры, хотя он напрямую не адресует перевод подготовленных операторов MySQLi в инструкции PDO.

Смежные вопросы