Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP会话类和$\u会话数组_Php_Oop_Session - Fatal编程技术网

PHP会话类和$\u会话数组

PHP会话类和$\u会话数组,php,oop,session,Php,Oop,Session,我实现了这个定制PHP会话类,用于将会话存储到MySQL数据库中: class Session { private $_session; public $maxTime; private $database; public function __construct(mysqli $database) { $this->database=$database; $this->maxTime['access'] = t

我实现了这个定制PHP会话类,用于将会话存储到MySQL数据库中:

class Session
{
    private $_session;
    public $maxTime;
    private $database;
    public function __construct(mysqli $database)
    {
        $this->database=$database;
        $this->maxTime['access'] = time();
        $this->maxTime['gc'] = get_cfg_var('session.gc_maxlifetime');

        session_set_save_handler(array($this,'_open'),
                array($this,'_close'),
                array($this,'_read'),
                array($this,'_write'),
                array($this,'_destroy'),
                array($this,'_clean')
                );

        register_shutdown_function('session_write_close');

        session_start();//SESSION START

    }

    public function _open()
    {
        return true;
    }

    public function _close()
    {
        $this->_clean($this->maxTime['gc']);
    }

    public function _read($id)
    {
        $getData= $this->database->prepare("SELECT data FROM 
                                            Sessions AS Session
                                            WHERE Session.id = ?");
        $getData->bind_param('s',$id);
        $getData->execute();

        $allData= $getData->fetch();
        $totalData = count($allData);
        $hasData=(bool) $totalData >=1;

        return $hasData ? $allData['data'] : '';
    }

    public function _write($id, $data)
    {
        $getData = $this->database->prepare("REPLACE INTO
            Sessions
            VALUES (?, ?, ?)");
        $getData->bind_param('sss', $id, $this->maxTime['access'], $data);

        return $getData->execute();
    }

    public function _destroy($id)
    {
        $getData=$this->database->prepare("DELETE FROM
            Sessions
            WHERE id = ?");
        $getData->bind_param('S', $id);
        return $getData->execute();
    }

    public function _clean($max)
    {
        $old=($this->maxTime['access'] - $max);

        $getData = $this->database->prepare("DELETE FROM Sessions WHERE access < ?");
        $getData->bind_param('s', $old);
        return $getData->execute();
    }
}

在每次页面刷新时,似乎会话['user']以某种方式被“重置”,我可以应用什么方法来防止这种行为?

也许你需要先做一下?

我以前有过这样的情况,会话似乎不会像应该的那样持续下去

当您更改页面时,您可以尝试检查sessionid是否保持不变,如果不手动设置的话

var_dump(session_id());

if (session_id()=="")
{
    if ($_GET["sessionid"])
    {
        session_id($_GET["sessionid"]);
    }
    elseif ($_POST["sessionid"])
    {
        session_id($_POST["sessionid"]);
    }

    session_start();
}
这更像是一个测试,看看这是否是问题所在。我不确定从查询字符串设置会话id会带来什么安全影响,但我怀疑它们不好

mysqli_stmt::fetch()
不返回表示行的数组,它只返回true或false。因此,在
\u read()

不能工作
$allData
将为
true
false
,并且不存在数组元素
$allData['data']

说:

将准备好的语句的结果提取到绑定的变量中。
这是更新后的代码!!!:-) 现在它完全工作了

<?php
class session {
    private $_session;
    public $maxTime;
    private $db;
    public function __construct() {
        $this->maxTime['access'] = time();
        $this->maxTime['gc'] = 21600; //21600 = 6 hours

        //it is session handler
        session_set_save_handler(array($this,'_open'),
                array($this,'_close'),
                array($this,'_read'),
                array($this,'_write'),
                array($this,'_destroy'),
                array($this,'_clean')
                );

        register_shutdown_function('session_write_close');

        session_start();//SESSION START
    }

    private function getDB() {
        $mysql_host = 'your_host';
        $mysql_user = 'user';
        $mysql_password = 'pass';
        $mysql_db_name = 'db_name';


        if (!isset($this->db)) {
            $this->db = new mysqli($mysql_host, $mysql_user, $mysql_password, $mysql_db_name);
            if (mysqli_connect_errno()) {
                printf("Error no connection: <br />%s\n", mysqli_connect_error());
                exit();
            }
        }

        return $this->db;
    }

    // O_O !!!
    public function _open() {
        return true;
    }


    public function _close() {
        $this->_clean($this->maxTime['gc']);
    }

    public function _read($id)  {       
        $stmt= $this->getDB()->prepare("SELECT session_variable FROM table_sessions 
                                            WHERE table_sessions.session_id = ?");
        $stmt->bind_param('s',$id);
        $stmt->bind_result($data);
        $stmt->execute();
        $ok = $stmt->fetch() ? $data : '';
        $stmt->close();
        return $ok;
    }

    public function _write($id, $data) {    
        $stmt = $this->getDB()->prepare("REPLACE INTO table_sessions (session_id, session_variable, session_access) VALUES (?, ?, ?)");
        $stmt->bind_param('ssi', $id, $data, $this->maxTime['access']);
        $ok = $stmt->execute();
        $stmt->close();
        return $ok;     
    }

    public function _destroy($id) {
    $stmt=$this->getDB()->prepare("DELETE FROM table_sessions WHERE session_id = ?");
    $stmt->bind_param('s', $id);
    $ok = $stmt->execute();
    $stmt->close();
    return $ok;
    }

    public function _clean($max) {
    $old=($this->maxTime['access'] - $max);
    $stmt = $this->getDB()->prepare("DELETE FROM table_sessions WHERE session_access < ?");
    $stmt->bind_param('s', $old);
    $ok = $stmt->execute();
    $stmt->close();
    return $ok;
    }
}
?>

我是唯一一个在标签中看到随机“not”的人吗?为什么会这样?在查询/准备/执行()失败的情况下,没有错误处理代码。卡森·迈尔斯:不,我也看到了。这真的很奇怪。在“会话”标签前有一个负号,我编辑了它;)正在会话类的构造函数中调用会话\u start()。只要他先创建会话类的一个实例,这就足够了吗?是的,每次页面刷新后sessionid都保持不变……我想知道在每次刷新时创建一个新的会话对象是否是实际问题(构造函数每次调用Session_start())。。。!我想我以后应该更仔细地阅读PHP文档…再次感谢大家!谢谢,现在人们可以正确使用它了;)
$allData= $getData->fetch();
$totalData = count($allData);
$hasData=(bool) $totalData >=1;
return $hasData ? $allData['data'] : '';
  public function _read($id)
  {
    $getData= $this->database->prepare("SELECT data FROM
      Sessions AS Session
      WHERE Session.id = ?
    ");
    if ( false===$getData ) {
      // now what?
    }

    $getData->bind_param('s',$id);
    $getData->bind_result($data);
    if ( false===$getData->execute() ) {
      // now what?
    }
    return  $getData->fetch() ? $data : '';
  }
<?php
class session {
    private $_session;
    public $maxTime;
    private $db;
    public function __construct() {
        $this->maxTime['access'] = time();
        $this->maxTime['gc'] = 21600; //21600 = 6 hours

        //it is session handler
        session_set_save_handler(array($this,'_open'),
                array($this,'_close'),
                array($this,'_read'),
                array($this,'_write'),
                array($this,'_destroy'),
                array($this,'_clean')
                );

        register_shutdown_function('session_write_close');

        session_start();//SESSION START
    }

    private function getDB() {
        $mysql_host = 'your_host';
        $mysql_user = 'user';
        $mysql_password = 'pass';
        $mysql_db_name = 'db_name';


        if (!isset($this->db)) {
            $this->db = new mysqli($mysql_host, $mysql_user, $mysql_password, $mysql_db_name);
            if (mysqli_connect_errno()) {
                printf("Error no connection: <br />%s\n", mysqli_connect_error());
                exit();
            }
        }

        return $this->db;
    }

    // O_O !!!
    public function _open() {
        return true;
    }


    public function _close() {
        $this->_clean($this->maxTime['gc']);
    }

    public function _read($id)  {       
        $stmt= $this->getDB()->prepare("SELECT session_variable FROM table_sessions 
                                            WHERE table_sessions.session_id = ?");
        $stmt->bind_param('s',$id);
        $stmt->bind_result($data);
        $stmt->execute();
        $ok = $stmt->fetch() ? $data : '';
        $stmt->close();
        return $ok;
    }

    public function _write($id, $data) {    
        $stmt = $this->getDB()->prepare("REPLACE INTO table_sessions (session_id, session_variable, session_access) VALUES (?, ?, ?)");
        $stmt->bind_param('ssi', $id, $data, $this->maxTime['access']);
        $ok = $stmt->execute();
        $stmt->close();
        return $ok;     
    }

    public function _destroy($id) {
    $stmt=$this->getDB()->prepare("DELETE FROM table_sessions WHERE session_id = ?");
    $stmt->bind_param('s', $id);
    $ok = $stmt->execute();
    $stmt->close();
    return $ok;
    }

    public function _clean($max) {
    $old=($this->maxTime['access'] - $max);
    $stmt = $this->getDB()->prepare("DELETE FROM table_sessions WHERE session_access < ?");
    $stmt->bind_param('s', $old);
    $ok = $stmt->execute();
    $stmt->close();
    return $ok;
    }
}
?>
CREATE TABLE IF NOT EXISTS `table_sessions` (
  `session_id` varchar(50) NOT NULL,
  `session_variable` text NOT NULL,
  `session_access` decimal(15,0) NOT NULL,
  PRIMARY KEY  (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;