2013-02-24 4 views
0

이 세션 클래스를이 article을 사용하여 빌드했습니다. 모든 규칙과 모든 정보를 준수했지만 코드가 작동하지 않습니다.PHP 세션 클래스가 작동하지 않습니다.

세션 클래스 : 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 나는 오류 500 내부 서버 오류가 나타난 것을 발견

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

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

echo $_SESSION['dims']; 

?> 

.

+0

오류를 기록하셨습니까? – kirugan

+0

그걸 시도했지만 실제로 오류가 나타나지 않았습니다. – Dimser

+0

글쎄, 500 에러는 서버가 비정상적이고 로깅을 켜는 것 (코드 및 서버 설정에서)보다 더 많이 발생한다는 것을 의미합니다. 명확한 오류 설명을 통해 우리는 훨씬 더 빨리 도울 수 있습니다. – kirugan

답변

1

귀하의 클래스가 PDO를 통해 연결을 설정했지만, 다음 튜토리얼에서는 MySQLi 준비 문을 사용합니다. 두 API는 서로 호환되지 않습니다. 나는 위의 전체 코드 블록을 변환하지 않을거야

 // 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에서 이에 해당하는 코드가 보일 것이다. PDO docs on bindParam()에는 다른 검색어도 파악할 수있는 충분한 예가 있습니다.

마지막으로 나는 우수 사례가 있지만을 권장합니다. 단, MySQLi 준비 문을 PDO 문으로 직접 변환하는 것은 아닙니다.

관련 문제