首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法在PHP中获取会话值并将其存储到数据库

无法在PHP中获取会话值并将其存储到数据库
EN

Stack Overflow用户
提问于 2018-07-11 04:48:20
回答 2查看 117关注 0票数 -2

我使用下面的代码在数据库中存储会话,当我尝试echo会话值时,我得到了错误,骗人帮助我做错了什么。

Session.class.php

代码语言:javascript
复制
<?php

/**
 * @category    Security
 * @version     1.0
 * @author      First Last <sanoj@lawrennce.com>
 * */
class mySessionHandler {

    private $_db = NULL;
    private $_table_name = 'sessions';
    private $_cookie_name = 'session_cookie';
    private $_seconds_till_expiration = 7200; // 2 hours
    private $_renewal_time = 300; // 5 minutes
    private $_expire_on_close = FALSE;
    private $_ip_address = FALSE;
    private $_user_agent = FALSE;
    private $_secure_cookie = FALSE;
    private $_session_id = '';
    private $_data = array();

    public function __construct(array $config) {
        $this->_setConfig($config);
        if ($this->_read()) {
            $this->_update();
        } else {
            $this->_create();
        }
        $this->_cleanExpired();
        $this->_setCookie();
    }

    public function regenerateId() {
        $old_session_id = $this->_session_id;
        $this->_session_id = $this->_generateId();
        $stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET time_updated = ?, session_id = ? WHERE session_id = ?");
        $stmt->execute(array(time(), $this->_session_id, $old_session_id));
        $this->_setCookie();
    }

    public function setData($key, $value) {
        $this->_data[$key] = $value;
        $this->_write();
    }

    public function unsetData($key) {
        if (isset($this->_data[$key])) {
            unset($this->_data[$key]);
        }
    }

    function getData($key) {
        return isset($this->_data[$key]) ? $this->_data[$key] : FALSE;
    }

    public function getAllData() {
        return $this->_data;
    }

    public function destroy() {
        if (isset($this->_session_id)) {
            $stmt = $this->_db->prepare("DELETE FROM {$this->_table_name} WHERE session_id = ?");
            $stmt->execute(array($this->_session_id));
        }
        setcookie($this->_cookie_name, '', time() - 31500000, NULL, NULL, NULL, NULL);
    }

    private function _read() {
        $session_id = filter_input(INPUT_COOKIE, $this->_cookie_name) ? filter_input(INPUT_COOKIE, $this->_cookie_name) : FALSE;
        if (!$session_id) {
            return FALSE;
        }
        $this->_session_id = $session_id;
        $stmt = $this->_db->prepare("SELECT data, time_updated, user_agent, ip_address FROM {$this->_table_name} WHERE session_id = ?");
        $stmt->execute(array($this->_session_id));
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($result !== FALSE && count($result) > 0) {
            if (!$this->_expire_on_close && (($result['time_updated'] + $this->_seconds_till_expiration) < time())) {
                $this->destroy();
                return FALSE;
            }
            if ($this->_ip_address && ($result['ip_address'] != $this->_ip_address)) {
                $this->_flagForUpdate();
                return FALSE;
            }
            if ($this->_user_agent && ($result['user_agent'] != $this->_user_agent)) {
                $this->_flagForUpdate();
                return FALSE;
            }
            $this->_checkUpdateFlag();
            $this->_checkIdRenewal();
            $user_data = unserialize($result['data']);
            if ($user_data) {
                $this->_data = $user_data;
                unset($user_data);
            }return TRUE;
        }return FALSE;
    }

    private function _create() {
        $this->_session_id = $this->_generateId();
        $stmt = $this->_db->prepare("INSERT INTO {$this->_table_name} (session_id, user_agent, ip_address, time_updated) VALUES (?, ?, ?, ?)");
        $stmt->execute(array($this->_session_id, $this->_user_agent, $this->_ip_address, time()));
    }

    private function _update() {
        $stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET time_updated = ? WHERE session_id = ?");
        $stmt->execute(array(time(), $this->_session_id));
    }

    private function _write() {
        if (count($this->_data) == 0) {
            $custom_data = '';
        } else {
            $custom_data = serialize($this->_data);
        }
        $stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET data = ?, time_updated = ? WHERE session_id = ?");
        $stmt->execute(array($custom_data, time(), $this->_session_id));
    }

    private function _setCookie() {
        setcookie(
                $this->_cookie_name, $this->_session_id, ($this->_expire_on_close) ? 0 : time() + $this->_seconds_till_expiration, // Expiration timestamp
                NULL, NULL, $this->_secure_cookie, // Will cookie be set without HTTPS?
                TRUE // HttpOnly
        );
    }

    private function _cleanExpired() {
        if (mt_rand(1, 1000) == 1) {
            $stmt = $this->_db->prepare("DELETE FROM {$this->_table_name} WHERE (time_updated + {$this->_seconds_till_expiration}) < ?");
            $stmt->execute(array(time()));
        }
    }

    private function _generateId() {
        $salt = 'x7^!bo3p,.$$!$6[&Q.#,//@i"%[X';
        $random_number = mt_rand(0, mt_getrandmax());
        $ip_address_fragment = md5(substr(filter_input(INPUT_SERVER, 'REMOTE_ADDR'), 0, 5));
        $timestamp = md5(microtime(TRUE) . time());
        $hash_data = $random_number . $ip_address_fragment . $salt . $timestamp;
        $hash = hash('sha256', $hash_data);
        return $hash;
    }

    private function _checkIdRenewal() {
        $stmt = $this->_db->prepare("SELECT time_updated FROM {$this->_table_name} WHERE session_id = ?");
        $stmt->execute(array($this->_session_id));
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($result !== FALSE && count($result) > 0) {
            if ((time() - $this->_renewal_time) > $result['time_updated']) {
                $this->regenerateId();
            }
        }
    }

    private function _flagForUpdate() {
        $stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET flagged_for_update = '1' WHERE session_id = ?");
        $stmt->execute(array($this->_session_id));
    }

    private function _checkUpdateFlag() {
        $stmt = $this->_db->prepare("SELECT flagged_for_update FROM {$this->_table_name} WHERE session_id = ?");
        $stmt->execute(array($this->_session_id));
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($result !== FALSE && count($result) > 0) {
            if ($result['flagged_for_update']) {
                $this->regenerateId();
                $stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET flagged_for_update = '0' WHERE session_id = ?");
                $stmt->execute(array($this->_session_id));
            }
        }
    }

    private function _setConfig(array $config) {
        if (isset($config['database'])) {
            $this->_db = $config['database'];
        } else {
            throw new Exception('Database handle not set!');
        }
        if (isset($config['cookie_name'])) {
            if (!ctype_alnum(str_replace(array('-', '_'), '', $config['cookie_name']))) {
                throw new Exception('Invalid cookie name!');
            } $this->_cookie_name = $config['cookie_name'];
        }
        if (isset($config['table_name'])) {
            if (!ctype_alnum(str_replace(array('-', '_'), '', $config['table_name']))) {
                throw new Exception('Invalid table name!');
            } $this->_table_name = $config['table_name'];
        }
        if (isset($config['seconds_till_expiration'])) {
            if (!is_int($config['seconds_till_expiration']) || !preg_match('#[0-9]#', $config['seconds_till_expiration'])) {
                throw new Exception('Seconds till expiration must be a valid number.');
            }
            if ($config['seconds_till_expiration'] < 1) {
                throw new Exception('Seconds till expiration can not be zero or less. Enable session expiration when the browser closes instead.');
            }
            $this->_seconds_till_expiration = (int) $config['seconds_till_expiration'];
        }
        if (isset($config['expire_on_close'])) {
            if (!is_bool($config['expire_on_close'])) {
                throw new Exception('Expire on close must be either TRUE or FALSE.');
            }
            $this->_expire_on_close = $config['expire_on_close'];
        }
        if (isset($config['renewal_time'])) {
            if (!is_int($config['renewal_time']) || !preg_match('#[0-9]#', $config['renewal_time'])) {
                throw new Exception('Session renewal time must be a valid number.');
            }
            if ($config['renewal_time'] < 1) {
                throw new Exception('Session renewal time can not be zero or less.');
            }
            $this->_renewal_time = (int) $config['renewal_time'];
        }
        if (isset($config['check_ip_address'])) {
            if (!is_string($config['check_ip_address'])) {
                throw new Exception('The IP address must be a string similar to this: \'172.16.254.1\'.');
            }
            if (!preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $config['check_ip_address'])) {
                throw new Exception('Invalid IP address.');
            }
            $this->_ip_address = $config['check_ip_address'];
        }
        if (isset($config['check_user_agent'])) {
            $this->_user_agent = substr($config['check_user_agent'], 0, 999);
        } if (isset($config['secure_cookie'])) {
            if (!is_bool($config['secure_cookie'])) {
                throw new Exception('The secure cookie option must be either TRUE or FALSE.');
            }
            $this->_secure_cookie = $config['secure_cookie'];
        }
    }

}

index.php

代码语言:javascript
复制
<?php


// Database connection
$pdo = new PDO('mysql:host=localhost;dbname=1video', 'sanoj', '123456', array(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING));

// -----------------------------------------------------------------------------------------

// Loads session handler
include_once('classes/session-class.php');

// SESSION HANDLER CONFIGRATION
$config['database']                 = $pdo;             // PDO Database handle
$config['cookie_name']              = 'sanoj'; // Name of the cookie
$config['table_name']               = 'sessions';       // Database table name
$config['seconds_till_expiration']  = 7200;             // How many seconds it takes before the session expires. Default is 2 hours.
$config['renewal_time']             = 300;              // How many seconds it takes before the session ID is renewed. Default is 5 minutes.
$config['expire_on_close']          = FALSE;            // The session is terminated when the browser is closed.
$config['secure_cookie']            = FALSE;            // Decides whether the cookie should only be set when a HTTPS connection exists.
$config['check_ip_address']         = filter_input(INPUT_SERVER, 'REMOTE_ADDR');        //$_SERVER['REMOTE_ADDR'] Will check the user's IP address against the one stored in the database. Make sure this is a string which is a valid IP address. FALSE by default.
$config['check_user_agent']         = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT');    //$_SERVER['HTTP_USER_AGENT']; Will check the user's user agent against the one stored in the database. FALSE by default.

try
{
    $session = new mySessionHandler($config);
}
catch (Exception $e) {
    echo $e->getMessage();
    exit;
}

get_session.php

代码语言:javascript
复制
<?php
        session_start();
        include_once('classes/session-class.php');
        $session = new mySessionHandler($config);
        // put your code here
        echo $config['cookie_name'];
        ?>

有没有人能把我做错的事分类。

当我将名称config['cookie_name'] = 'sanoj';更改为config['cookie_name'] = 'sanoj';以在数据库中创建新行,而不是更新时,数据库中的会话值也不会被破坏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-14 17:15:08

设置会话值

代码语言:javascript
复制
$session->setData('myKey', 'myValue');

要获得会话值,请使用下面的方法。

代码语言:javascript
复制
echo $session->getData('myKey');

其中myKey为会话名,myValue为会话值。

票数 1
EN

Stack Overflow用户

发布于 2018-07-11 05:16:49

如果您运行的是get_session.php,请将其编辑为:

代码语言:javascript
复制
<?php
session_start();

include_once('classes/session-class.php');

$pdo = new PDO('mysql:host=localhost;dbname=1video', 'sanoj', '123456', array(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING));

$config['database']                 = $pdo;             // PDO Database handle
$config['cookie_name']              = 'sanoj'; // Name of the cookie
$config['table_name']               = 'sessions';       // Database table name
$config['seconds_till_expiration']  = 7200;             // How many seconds it takes before the session expires. Default is 2 hours.
$config['renewal_time']             = 300;              // How many seconds it takes before the session ID is renewed. Default is 5 minutes.
$config['expire_on_close']          = FALSE;            // The session is terminated when the browser is closed.
$config['secure_cookie']            = FALSE;            // Decides whether the cookie should only be set when a HTTPS connection exists.
$config['check_ip_address']         = filter_input(INPUT_SERVER, 'REMOTE_ADDR');        //$_SERVER['REMOTE_ADDR'] Will check the user's IP address against the one stored in the database. Make sure this is a string which is a valid IP address. FALSE by default.
$config['check_user_agent']         = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT');    //$_SERVER['HTTP_USER_AGENT']; Will check the user's user agent against the one stored in the database. FALSE by default.

try
{
    $session = new mySessionHandler($config);
    echo $config['cookie_name'];
}
catch (Exception $e) {
    echo $e->getMessage();
    exit;
}

?>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51273672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档