php 会话技术cookie 与 session

1、cookie的使用

cookie 的设置函数: setcookie(name, value, expire, path, domain, secure, httponly)

name 表示需要设置的cookie的名称

value 表示需要设置的cookie的值

expire 表示cookie的过期时间,采用的是时间截的格式

path  表示Cookie 有效的服务器路径。 设置成 '/' 时,表示cookie作用于服务器的根目录,对整个根目录都有效。 如果设置成 '/foo/', Cookie 仅仅对 服务器/foo/ 目录及其子目录有效(比如 /foo/bar/即在父级目录下定义cookie,那么在子目录下可以访问,如果在子目录下定义cookie,那么父级目录下是不可以访问的。 默认值是设置 Cookie 时的当前目录

domain Cookie 的有效域名/子域名。 设置成子域名(例如 'www.example.com'),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。 要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 'example.com')。如果不设置,那么只能在当前的域名下使用。

secure 表示设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。 设置成 TRUE 时,只有安全连接存在时才会设置 Cookie。 如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie (通过 $_SERVER["HTTPS"] 判断)。false表示在任何的协议下都能进行传输

httponly 设置成 TRUE,Cookie 仅可通过 HTTP 协议访问。 这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。 要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。 PHP 5.2.0 中添加。 TRUEFALSE, 即不能用document.cookie来读取

获取cookie值用$_COOKIE[key]来获取,判断是否存在cookie用 isset($_COOKIE[key]),删除cookie时,先设置过期setcookie(key, '', time()-1)  然后再删除cookie unset($_COOKIE[key])

注意: 在设置cookie时,前面不能的输出如 echo , var_dump, print_r等等

在设置cookie值的时候一般cookie的值是字符串,如果是其他类型的,需要利用json_encode, serialize, 或字符串拼接的形式转成字符串,再存入cookie中。

php代码

<?php
header('content-type:application/json');
ini_set('displayer_errors', true);

class Cookie{
    private $data;
    public function __construct() {
        $this->data = $_POST;
    }

    public function init() {
        if($this->data['name'] && $this->data['age']) {
            //读取cookie
            $data = $_COOKIE['info'] ? json_decode($_COOKIE['info'], true):  '';
            //设置cookie值
            setcookie('info', json_encode([
                'name'=> $this->data['name'],
                'age' => $this->data['age'],
                'logo' => time()
            ]), time()+1*24*3600);
            //返回ajax请求
            echo json_encode([
                'code' => 0,
                'name' => $data['name'] ?? '',
                'age' => $data['age'] ?? '',
                'time' => $data['logo']? date('Y-m-d H:i:s', $data['logo']): ''
            ]);
        }
    }
}
$c = new Cookie();
$c->init();
?>

html代码

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./resource/bootstrap.css">
    <script src="./resource/jquery.js"></script>
</head>
<body>
<input type="button" value="点击" class="btn btn-primary">
<script>
    $(()=> {
        $('input[type=button]').click(function() {
            $.post('./page.php', {'name': 'aaa', 'age': 12}, function(res) {
                console.log(res);
            })
        });
    })
</script>
</body>
</html>

 2、session的使用

相比cookie而言session是服务端技术,由于cookie每次都携带数据到服务端,这样的话1、效率比较底; 2、安全性比较低

session是一个存储在服务端的技术,当浏览器关闭后,那么session也就失效了

session的运行流程:

session 保存文件的地址:

session文件的存储路径:取决于PHP的配置文件:php.ini(如下图)

 session 用途: 可以实现服务器间多个文件的数据共享

 session 的数据类型除了资源型之外的任意类型的数据, 同时session的key值只能是字符型,不能为整型

 session 的具体代码实现:

<?php
ini_set('display_errors', true);
class Manager{
    private $session_arr = [];
    public function __construct() {
        session_start();
    }

    /**创建session
     * @param $key
     * @param $val
     * @return mixed
     */
    public function createSession($key, $val) {
        $this->session_arr[$key] = $val;
        return $_SESSION[$key] = $val;
    }

    /**删除单个session
     * @param $name
     * @return bool
     */
    public function removeSingleSession($name) {
        if($_SESSION[$name]) {
            unset($_SESSION[$name], $this->session_arr[$name]);
            return true;
        }
        return false;
    }

    /**
     * 删除所有的session
     */
    public function removeAllSession() {
        foreach($this->session_arr as $key => $val) {
            unset($_SESSION[$key]);
        }
        $this->session_arr = [];
    }

    /*获取session
     * @param string $name
     * @return mixed|string
     */
    public function getSession($name = '') {
        if($name) {
            return $_SESSION[$name] ?? '';
        }
        return $_SESSION;
    }
}
?>

注意:这里删除所有的session不能直接unset($_SESSION),因为这里面有系统内置的内容,可以遍历进行删除,如以上的例子

session_start()声明开始session文件操作

session_destroy()是删除session的文件

session_name() 是获取session的名字

删除内存中的session 只需要$SESSION = [],或者 session_unset()

session_set_save_handler($open, $close, $read, $write, $destroy, $gc) 改写session的存储机制,具体参数如下:

session的配置

 通常,如果是非常规性的配置,可以通过ini_set来配置php.ini里面的配置项,如下

<?php
header('content-type:text/html;charset= utf-8');
ini_set('display_errors', true);
ini_set('session.save_path', 'd:/test');        //改变cookie的存储路径
ini_set('session.gc_divisor', 1000);            //添加session删除的概率,session删除的概率是session.gc_probability / session.gc_divisor
ini_set('session.gc_maxlifetime', 60);          //当session的存在时,页面60s没有操作,那么session自动失效
?>

 改写session 的存储机制(注意测试Mysql在执行的过程中是否有误

一,设计mysql表

CREATE TABLE IF NOT EXISTS `session` (
    sid INT UNSIGNED NOT NULL PRIMARY KEY COMMENT "session ID",
    content TEXT NOT NULL COMMENT "session content",
    lasttime INT UNSIGNED NOT NULL COMMENT "last time"
)CHARSET=utf8 ENGINE=innodb;

二、连接Mysql

<?php
final class DB {
    private static $db;
    private function __clone() {}
    private function __construct() {
        $config = parse_ini_file('./db.ini');
        $mysqli = new Mysqli($config['host'], $config['user'], $config['password'], $config['dbname'], $config['port']);
        if($mysqli->connect_errno) {
            exit('服务器连接错误'.$mysqli->connect_error);
        }
        $mysqli->set_charset($config['charset']);
        self::$db = $mysqli;
    }
    public static function getInstance() {
        if(!self::$db instanceof Mysqli) {
            new DB();
        }
        return self::$db;
    }
}
?>

三,改写session存储机制

<?php
ini_set('display_errors', true);
//把以下的字段改成字定义模式
ini_set('session.save_handler', 'user');
require_once('./DB.php');
//参数一表示session_start时执行的函数
//参数二表示脚本结束时执行的函数
//参数三表示读取session中的数据时执行的函数
//参数四表示向session中写入数据时执行的函数
//参数五表示销毁session时执行的函数
//参数五表示session过期后执行的函数
//注意:所有的函数必需返回一个布尔值
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');
function open() {
    DB::getInstance();
    return true;
}
function close() {
//    echo '已经关闭了';
    return true;
}
function read($sid) {
    $sql = sprintf('SELECT `session_content` FROM `session` WHERE `session_id = "%s"`', $sid);
    $res = DB::getInstance()->query($sql);
    $content = null;
    if($res && $row = $res->fetch_assoc()) {
        $content = $row['session_content'];
        $res->free();
    }
    return $content;
}

function write($sid, $content) {
    $sql = 'INSERT INTO `session` VALUES ("%s", "%s", %d) ON DUPLICATE KEY UPDATE `session_content` = VALUES(`session_content`)';
    $sql = sprintf($sql, $sid, addslashes($content), time());
    $res = DB::getInstance()->query($sql);
    if(!$res) {
        echo DB::getInstance()->error;
        exit;
    }
    return DB::getInstance()->query($sql);
}

function destroy($sid) {
    $sql = sprintf('DELETE FROM `session` WHERE `session_id`="%s"', $sid);
    return DB::getInstance()->query($sql);
}

function gc($lifetime) {
    $time = time() + $lifetime;
    $sql = sprintf('DELETE FROM `session` WHERE `last_time` < %d', $time);
    return DB::getInstance()->query($sql);
}
session_start();
$_SESSION['name'] = 'aaaa';
$_SESSION['age'] = 30;
原文地址:https://www.cnblogs.com/rickyctbu/p/10961622.html