Php 会话类未正确跟踪会话id
这是我正在使用的会话类。 在每个页面上重新生成会话id是否是一个好主意,因为这正是我打算做的。 在每个页面上重新生成会话id时,write函数会执行以下操作:0(rowCount())选择0键从插入的getkey函数1中选择。 当(从rowCount()中)1从getkey函数中选择了1个key,从destroy函数中选择了1个destroct时,read函数将正常工作。 有时我会成功选择0个读取数据记录 0 destroy delete records成功地从destroy函数中删除记录,但它应该在read函数、getkey函数和destroy函数中进行选择,因为where子句中的id是数据库表中的id。 其他情况下,我将获得1“读取选定项”0“成功选定关键记录”0“删除旧会话id”并插入新会话id(从写入功能),就像1“读取选定项”1“选定关键项”1“销毁”。 通过read函数,where子句的id将是它应该能够选择的id,即db中的id。这与键和删除功能相同。 有时我会尝试插入两个id,因为已经生成了另一个id,但如果在db中将“设置时间”设置为“唯一”,则不会插入,但如果时间不相同(测试转到另一页),我会在db表中使用另一个id的行。有时在正确的行中只是一个错误的id(不是来自写入函数的id)。没有新行,只有不同的id。会话id是db表中的主键。我确实有点问题,比如一次点击鼠标,两次点击,这可能是原因之一。非常感谢您的帮助。 附注:第5.2.16条 情况1读取选定的0键选择0销毁或如果1读取选定的1键1销毁;为那些第123条的人说id。在页面$id=session_id()和echo$id的php部分的末尾,它是;比如说321。然后在信息回荡的页面底部。 选择0个键结果,where子句的id为321。 然后,加密后的数据会被回显。然后0写入选择1写入成功插入。 这正常吗Php 会话类未正确跟踪会话id,php,session,pdo,Php,Session,Pdo,这是我正在使用的会话类。 在每个页面上重新生成会话id是否是一个好主意,因为这正是我打算做的。 在每个页面上重新生成会话id时,write函数会执行以下操作:0(rowCount())选择0键从插入的getkey函数1中选择。 当(从rowCount()中)1从getkey函数中选择了1个key,从destroy函数中选择了1个destroct时,read函数将正常工作。 有时我会成功选择0个读取数据记录 0 destroy delete records成功地从destroy函数中删除记录,但它
enter code here
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){
$httponly = true;
// hash algorithm to use for the session id.(use hash_algos() to get a list of available hashs.)
$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, not url variables.
ini_set('session.use_only_cookies',1);
//get session cookie parameters
$cookieParams = session_get_cookie_params();
$domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
session_set_cookie_params($cookieParams["lifetime"],$cookieParams["path"],
//$cookieparams["domain"],$secure,$httponly);
$domain,$secure,$httponly);
// change session name
session_name($session_name);
session_name('identitysession');
// 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);
}
protected $db = null;
function open(){
if(is_null($this->db)){
$user = 'myuser';
$pass = 'mypassword';
try{
$this->db = new PDO( 'mysql:host=127.0.0.1;dbname= mydb',$user,$pass,
array(
PDO::ATTR_ERRMODE =>PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE=> PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES =>false));
}catch (PDOException $e){
echo 'Connection failed:'.$e->getMessage();
}
echo 'open open','<br/>';// the echo for testing
return true;
}
else{
echo 'not open','<br/>';// the echo for testing
exit();
}
}
function close(){
$this->db = null;
echo 'closed closed','<br/>';// the echo for testing
return true;
}
function read($id){
$timeout = time()-(30*60);
echo $id,'<br/>';// the echo for testing
if(!isset($this->read_stmt)){
try{
$this->read_stmt = $this->db->prepare("SELECT id,data,set_time FROM mydbtable WHERE id= :id LIMIT 1 ");
}catch(PDOException $e){
echo 'Unable to select from database read:'.$e->getMessage();
}
}
if(isset($this->read_stmt)){
$this->read_stmt->bindParam(':id',$id, PDO::PARAM_STR);
$this->read_stmt->execute();
$row = $this->read_stmt->fetch(PDO::FETCH_ASSOC);
$idrow = $row['id'];
echo 'selected id <br/>' . $idrow,'<br/>';// the echo for testing the selected id of db
$read_count = $this->read_stmt->rowCount();
echo $read_count. " Read data records selected successfully<br/>";// the echo for testing
if($read_count > 0 && $row !=''){
$data =$row['data'];
$time_past = $row['set_time'];
if( $time_past < $timeout){
echo 'nogood time out';//not completed yet
}
elseif($time_past > $timeout){
echo 'read getting data','<br/>';// the echo for testing
$key = $this->getkey($id);
echo 'selected id for key <br/>' . $id,'<br/>';// the echo for testing
$data = $this->decrypt($data, $key);
echo 'Data','<br/>';// the echo for testing
echo $data,'<br/>';// the echo for testing
return $data;
}
}
elseif($read_count < 1 && $row ==''){
return '';
}
}
}
function write($id, $data){
$key = $this->getkey($id);
$data = $this->encrypt($data, $key);
$time = time();
if(!isset($this->w_stmt)){
try{
$this->w_stmt = $this->db->prepare("SELECT data FROM mydbtable WHERE id= :id LIMIT 1 ");
}catch(PDOException $e){
echo 'Unable to select from database:'.$e->getMessage();
}
}
if(isset($this->w_stmt)){
try{
$this->w_stmt->execute(array(':id'=>$id));
$row = $this->w_stmt->fetch(PDO::FETCH_ASSOC);
}catch(PDOException $e){
echo 'Unable something from database:'.$e->getMessage();
}
$w_count = $this->w_stmt->rowCount();
echo $w_count. "W stmt records selected successfully";// the echo for testing
if($w_count > 0 && $row !=''){
try{
$this->w_stmt =$this->db->prepare("UPDATE mydbtable SET id = :id,
set_time = :time,data = :data, session_key = :session_key");
$this->w_stmt->execute(array(':id'=>$id,':time'=>$time,':data'=>$data,
':session_key'=>$key));
$wri_count = $this->w_stmt->rowCount();
echo $wri_count. "records updated successfully";// the echo for testing
}catch (PDOException $e){
echo 'Can not update the database:'.$e->getMessage();// the echo for testing
}
}
elseif($w_count < 1 && $row == ''){
try{
$this->w_stmt =$this->db->prepare("INSERT INTO mydbtable (id,set_time,data,session_key)
VALUES(:id,:time,:data,:session_key)");
$this->w_stmt->execute(array(':id'=>$id,':time'=>$time,':data'=>$data,
':session_key'=>$key));
$write_count = $this->w_stmt->rowCount();
echo $write_count. "w stmt records inserted successfully<br/>";// the echo for testing
echo $id;
}catch (PDOException $e){
echo 'Can not insert the database:'.$e->getMessage();
}
}
}// if set
}
function destroy($id){
echo $id,'<br/>';// the echo for testing
if(!isset($this->delete_stmt)){
try{
$this->delete_stmt = $this->db->prepare("DELETE FROM mydbtable WHERE id = :id");
}catch(PDOException $e){
echo 'Unable to delete from database:'.$e->getMessage();
}
}
if(isset($this->delete_stmt)) {
$this->delete_stmt->bindValue(':id',$id,PDO::PARAM_STR);
$this->delete_stmt->execute();
$delete_count = $this->delete_stmt->rowCount();
echo $delete_count . " destroy delete records successfully<br/>";// the echo for testing
echo 'delete ','<br/>';// the echo for testing
return true;
}
}
function gc($max){
if(!isset($this->gc_stmt)){
try{
$this->gc_stmt = $this->db->prepare("DELETE FROM mydbtable WHERE set_time < :set_time");
}catch(PDOException $e){
echo 'Unable to delete from database:'.$e->getMessage();
}
}
if(isset($this->gc_stmt)){
$old = time() - $max;
$this->gc_stmt->execute(array(':set_time'=>$old));
$gc_count = $this->gc_stmt->rowCount();
echo $gc_count. " gc records successfully";// the echo for testing
}
return true;
}
private function getkey($id){
echo $id,'<br/>';// the echo for testing
if(!isset($this->key_stmt)){
try{
$this->key_stmt = $this->db->prepare("SELECT session_key FROM mydbtable WHERE id = :id limit 1");
}catch(PDOException $e){
echo 'Unable to select from database for key:'.$e->getMessage();
}
}
if(isset($this->key_stmt)){
$this->key_stmt->execute(array(':id'=>$id));
$row = $this->key_stmt->fetch(PDO::FETCH_ASSOC);
$key_count = $this->key_stmt->rowCount();
echo $key_count. " key records selected successfully<br/>";
if($key_count > 0 && $row !=''){
echo 'key getting key','<br/>';// the echo for testing
$key = $row['session_key'];
return $key;
}
elseif($key_count < 1 && $row == ''){
$random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()),true));
return $random_key;
}
}
}
private function encrypt($data,$key){
$salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH';
$key = substr(hash('sha256',$salt.$key.$salt), 0, 32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv));
echo 'encrypted','<br/>';// the echo for testing
return $encrypted;
}
private function decrypt($data, $key){
$salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH';
$key = substr(hash('sha256',$salt.$key.$salt), 0, 32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv);
echo 'decript','<br/>';// the echo for testing
return $decrypted;
}
在此处输入代码
课堂{
函数_u构造(){
//设置自定义会话函数。
会话设置保存处理程序(数组($this,'open')、数组($this,'close')、数组($this,'read')、数组($this,'write')、数组($this,'destroy')、数组($this,'gc'));
//当使用对象作为保存处理程序时,此行可防止出现意外效果。
寄存器关闭功能(“会话写入关闭”);
}
函数启动会话($session\u name,$secure){
$httponly=true;
//用于会话id的哈希算法。(使用hash_algos()获取可用哈希的列表。)
$session_hash='sha512';
//检查哈希是否可用
if(在数组($session\u hash,hash\u algos())中){
//设置哈希函数。
ini_集('session.hash_函数',$session_hash);
}
//哈希的每个字符有多少位。
ini_集('session.hash_bits_per_character',5);
//强制会话仅使用cookie,而不使用url变量。
ini\u集('会话。仅使用\u cookies',1);
//获取会话cookie参数
$cookieParams=会话获取cookie参数();
$domain=($\u服务器['HTTP\u主机]!='localhost')?$\u服务器['HTTP\u主机]:false;
会话设置cookie参数($cookieParams[“lifetime”],$cookieParams[“path”],
//$cookieparams[“域”],$secure,$httponly);
$domain、$secure、$httponly);
//更改会话名称
会话名称($session\u name);
会话名称(“identitysession”);
//现在我们可以开始会话了
会话_start();
//此行将重新生成会话并删除旧会话。
//它还会在数据库中生成一个新的加密密钥。
会话\u重新生成\u id(true);
}
受保护的$db=null;
函数open(){
如果(为空($this->db)){
$user='myuser';
$pass='mypassword';
试一试{
$this->db=newpdo('mysql:host=127.0.0.1;dbname=mydb',$user,$pass,
排列(
PDO::ATTR_ERRMODE=>PDO::ERRMODE_异常,
PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES=>false));
}捕获(PDO$e){
回显“连接失败:”。$e->getMessage();
}
echo“open open”,“
”;//用于测试的echo
返回true;
}
否则{
回显“未打开”,“
;”//用于测试的回显
退出();
}
}
函数关闭(){
$this->db=null;
echo“closed closed”,“
;”//用于测试的echo
返回true;
}
函数读取($id){
$timeout=time()-(30*60);
echo$id,
;//用于测试的echo
如果(!isset($this->read stmt)){
试一试{
$this->read_stmt=$this->db->prepare(“从mydbtable中选择id、数据、设置时间,其中id=:id限制1”);
}捕获(PDO$e){
echo“无法从数据库中选择读取:”。$e->getMessage();
}
}
如果(设置($this->read_stmt)){
$this->read_stmt->bindParam(':id',$id,PDO::PARAM_STR);
$this->read_stmt->execute();
$row=$this->read\u stmt->fetch(PDO::fetch\u ASSOC);
$idrow=$row['id'];
echo“selected id
”。$idrow,
;//用于测试db的所选id的echo
$read\u count=$this->read\u stmt->rowCount();
echo$read_count.“已成功选择读取数据记录”
;//用于测试的echo
如果($read_count>0&&$row!=''){
$data=$row['data'];
$time_pass=$row['set_time'];
如果($time_pass<$timeout){
echo'nogood timeout';//尚未完成
}
elseif($time\u pass>$timeout){
echo“读取获取数据”,“
”;//用于测试的echo
$key=$this->getkey($id);
echo“为键
选择的id”。$id,
;//用于测试的echo
$data=$this->decrypt($data,$key);
回显“数据”,“
”;//用于测试的回显
echo$data,
;//用于测试的echo
返回$data;
}
}
elseif($read_count<1&&$row=''){
返回“”;
}
}
}
F