PHP 自定义 Session 处理程序
PHP Custom Session Handler
我在自定义 session class 中使用 session_set_save_handler 来使用数据库存储。我使用数据库 session 存储已经一年多了。这一直运行良好,我将近一年前编写的验证码也是如此。我现在遇到的问题是验证码不再输出图像。如果我将 require_once 删除到 session class,图像将被输出,但代码将被保存,就像单独使用 session_start 而不是自定义 class 一样。如果我需要 session class 图像不会显示,但代码是按预期编写的。我已经使用相同的代码将近一年了,没有任何问题。我完全不知道发生了什么。
<?php
require_once('database.php');
require_once('config.php');
class FileSessionHandler
{
private $database;
private $life_time;
public function FileSessionHandler(){
$this->life_time = get_cfg_var("session.gc_maxlifetime");
$this->database = new database();
$this->database->newConnection (db_host,db_users_name,db_users_pass,db_users_prefix . db_users);
session_set_save_handler(
array(&$this,'open'),
array(&$this,'close'),
array(&$this,'read'),
array(&$this,'write'),
array(&$this,'destroy'),
array(&$this,'gc')
);
register_shutdown_function('session_write_close');
session_start();
}
function open($savePath,$sessionName){
return TRUE;
}
function close(){
return TRUE;
}
function read($id){
$data = "";
$time = time();
$newid = $this->database->sanitizeData($id);
$sql = "SELECT `session_data` FROM `" . tb_site_sessions . "`
WHERE `session_id`='{$newid}' AND `expires`>{$time}";
$this->database->executeQuery($sql);
if($this->database->numRows() > 0) {
$row = $this->database->getRows();
$data = $row['session_data'];
}
return $data;
}
function write($id,$data){
$newid = $this->database->sanitizeData($id);
$newdata = $this->database->sanitizeData($data);
$time = time() + $this->life_time;
$sql = "INSERT INTO `" . tb_site_sessions . "`
(`session_id`,`session_data`,`expires`)
VALUES('{$newid}','{$newdata}',{$time}) ON DUPLICATE KEY UPDATE
session_data='{$newdata}',expires={$time}";
$this->database->executeQuery($sql);
return TRUE;
}
function destroy($id){
$newid = $this->database->sanitizeData($id);
$sql = "DELETE FROM `" . tb_site_sessions . "` WHERE `session_id`='{$newid}'";
$this->database->executeQuery($sql);
return TRUE;
}
function gc($maxlifetime){
$time = time();
$sql = "DELETE FROM `" . tb_site_sessions . "` WHERE `expires`<'{$time}'";
$this->database->executeQuery($sql);
return TRUE;
}
}
?>
调用方法:
require_once('site-sessions.php');
$handler = new FileSessionHandler();
图片headers:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
找到问题了,很简单。在配置文件中,php 标记前有一个空行。空行混淆了 headers 和 session 调用。我什至没有考虑查看配置文件,因为它已经有一段时间没有更改了。只是包括答案以防其他人遇到类似情况。
我在自定义 session class 中使用 session_set_save_handler 来使用数据库存储。我使用数据库 session 存储已经一年多了。这一直运行良好,我将近一年前编写的验证码也是如此。我现在遇到的问题是验证码不再输出图像。如果我将 require_once 删除到 session class,图像将被输出,但代码将被保存,就像单独使用 session_start 而不是自定义 class 一样。如果我需要 session class 图像不会显示,但代码是按预期编写的。我已经使用相同的代码将近一年了,没有任何问题。我完全不知道发生了什么。
<?php
require_once('database.php');
require_once('config.php');
class FileSessionHandler
{
private $database;
private $life_time;
public function FileSessionHandler(){
$this->life_time = get_cfg_var("session.gc_maxlifetime");
$this->database = new database();
$this->database->newConnection (db_host,db_users_name,db_users_pass,db_users_prefix . db_users);
session_set_save_handler(
array(&$this,'open'),
array(&$this,'close'),
array(&$this,'read'),
array(&$this,'write'),
array(&$this,'destroy'),
array(&$this,'gc')
);
register_shutdown_function('session_write_close');
session_start();
}
function open($savePath,$sessionName){
return TRUE;
}
function close(){
return TRUE;
}
function read($id){
$data = "";
$time = time();
$newid = $this->database->sanitizeData($id);
$sql = "SELECT `session_data` FROM `" . tb_site_sessions . "`
WHERE `session_id`='{$newid}' AND `expires`>{$time}";
$this->database->executeQuery($sql);
if($this->database->numRows() > 0) {
$row = $this->database->getRows();
$data = $row['session_data'];
}
return $data;
}
function write($id,$data){
$newid = $this->database->sanitizeData($id);
$newdata = $this->database->sanitizeData($data);
$time = time() + $this->life_time;
$sql = "INSERT INTO `" . tb_site_sessions . "`
(`session_id`,`session_data`,`expires`)
VALUES('{$newid}','{$newdata}',{$time}) ON DUPLICATE KEY UPDATE
session_data='{$newdata}',expires={$time}";
$this->database->executeQuery($sql);
return TRUE;
}
function destroy($id){
$newid = $this->database->sanitizeData($id);
$sql = "DELETE FROM `" . tb_site_sessions . "` WHERE `session_id`='{$newid}'";
$this->database->executeQuery($sql);
return TRUE;
}
function gc($maxlifetime){
$time = time();
$sql = "DELETE FROM `" . tb_site_sessions . "` WHERE `expires`<'{$time}'";
$this->database->executeQuery($sql);
return TRUE;
}
}
?>
调用方法:
require_once('site-sessions.php');
$handler = new FileSessionHandler();
图片headers:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
找到问题了,很简单。在配置文件中,php 标记前有一个空行。空行混淆了 headers 和 session 调用。我什至没有考虑查看配置文件,因为它已经有一段时间没有更改了。只是包括答案以防其他人遇到类似情况。