簡體   English   中英

PHP會話類不起作用

[英]PHP session class doesn't work

我已使用本文構建了該會話類。.我確實可以確定我已遵循所有規則和所給的所有信息,但是我的代碼無法正常工作。

會話類: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*ewr4n39=E@rAsp7c-Ph@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*ewr4n39=E@rAsp7c-Ph@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內部服務器錯誤。

您的班級已經通過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.
     }

我不會在上面翻譯整個代碼塊,但這應該可以幫助您入門。 bindParam()PDO文檔有足夠的示例,您還應該能夠弄清楚其他查詢。

最后,盡管沒有直接解決將MySQLi准備的語句轉換為PDO語句的問題,但我還是推薦了MySQL開發人員PDO教程 ,該示例很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM