zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    Windows10下Opencv4+CMake+MinGW64+VSC安装教程
    相机标定问题-实践操作流程
    eNSP仿真学习,网络入门!
    SFTP服务的使用!!
    树莓派B+使用入门&RPI库安装&wringPi库安装
    Python基本语法初试
    基于51单片机+DAC0832的信号发生器
    各种标志位的含义
    根文件系统ramdisk.image.gz && uramdisk.image.gz
    Linux中/etc/inittab文件
  • 原文地址:https://www.cnblogs.com/rickyctbu/p/10961622.html
Copyright © 2011-2022 走看看