• COOKIE和SESSION及案例



    1.cookie和session

    1.1Cookie的工作原理

    1. 浏览器端第一次发送请求到服务器端
    2. 服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端
    3. 浏览器端再次访问服务器端时会携带服务器端创建的Cookie
    4. 服务器端通过Cookie中携带的数据区分不同的用户

    1.2.Session的工作原理

    • 浏览器端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie,(name``JSESSIONID的固定值,valuesession对象的ID),然后将该Cookie发送至浏览器端

    • 浏览器端发送第N(N>1)次请求到服务器端,浏览器端访问服务器端时就会携带该nameJSESSIONIDCookie对象

    • 服务器端根据nameJSESSIONID的Cookie``value(sessionId),去查询Session对象,从而区分不同用户。nameJSESSIONIDCookie不存在(关闭或更换浏览器),返回1中重新去创建Session与特殊的Cookie
      nameJSESSIONIDCookie存在,根据value中的SessionId去寻找session对象

    • valueSessionId不存在**(Session对象默认存活30分钟)**,返回1中重新去创建Session与特殊的Cookie
      valueSessionId存在,返回session对象

    1.3session和cookie工作图解

    💎💎 如下是session工作图解

    
    
    session_start();
    
    /**
     * 启动会话做了二件事
     * 1. 浏览器: 创建会话ID: PHPSESSID, 一串md5加密的字符串
     * 2. 服务器: 创建与浏览器会话ID对应的会话文件,一个会话文件对应一个用户
     */
    
    // 1. 设置session值
    $_SESSION['email'] = 'admin@php.cn';
    $_SESSION['password'] = sha1(md5('123456'). 'php.cn123');
    

    在这里插入图片描述

    没访问之前为空

    在这里插入图片描述

    💎💎自动生成会话ID文件

    在这里插入图片描述

    就是当产生会话的时候,就是你访问一个网站,会在浏览器生成一个会话ID,该ID标识了你这个用户,服务器会生成一个对应该ID的文件 ,该ID文件记录着你在网站进行的一系列操作(比如你访问了哪个网页,买了哪些东西),然后当你下一次访问该网站的时候,浏览器携带会话ID去和服务器对应的ID文件夹比对,然后确定你在网站进行了哪些操作,因为http协议是无连接的(就是你每访问一次服务器都要建立一次连接,这样你登录了网站,下一次访问又要登录网站,但是有了会话ID,一比对,就自动跳转到你上一次你访问的网页)

    ⚠️⚠️ 如下是cookie工作图解

    在这里插入图片描述
    COOKIE

    
     
    setcookie('user[name]','yk');
    setcookie('user[password]','yksad');
    setcookie('user[email]','yksfd');
    /**
     * 将过多信息存储在客户端,并不适合
     * 1. 数量受限: 30个
     * 2. 空间受限: 4k
     * 3. 安全隐患: 天生不可避免
     *
     * 所以, 会话信息推荐存储在服务器端
     * 客户端只需要保存一个会话ID,用于标识访问身份即可
     */
    
    
    

    1.4session和cookie总结

    ⚠️⚠️cookie是浏览器存储信息的对象,session是服务器存储信息的对象,两者都存储着用户信息,每次访问服务器时,浏览器携带cookie和服务器的session进行比对,来确定用户信息。

    2.登录系统案例

    2.1CSS/index.php

    nav{
        height: 40px;
        background-color: deepskyblue;
        padding: 0 20px;
        display: flex;
        place-content: space-between;
        place-items: center;
    }
    nav>a{
        color: white;
        text-decoration: none;
    }
    
    

    2.2CSS/style.php

    body {
        display: flex;
        flex-direction: column;
        text-align: center;
        color: #555;
        font-weight: 300;
        /* background-color: lightcyan; */
        background: linear-gradient(to left, lightcyan, white);
    }
    body h3 {
        font-weight: 300;
        font-size: 20px;
        margin-bottom: 10px;
    }
    body form {
        width: 240px;
        padding: 20px;
        box-sizing: border-box;
        background: linear-gradient(to left top, lightskyblue, white);
        color: white;
        text-shadow: 0.5px 0.5px 0.5px #000;
        margin: auto;
        border-radius: 5px;
        box-shadow: 0 0 5px #aaa;
    }
    body form > div {
        height: 36px;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    body form div:last-of-type {
        display: flex;
        justify-content: center;
    }
    body form input {
        border: none;
        outline: none;
        padding-left: 5px;
        height: 20px;
    }
    body form input:hover {
        box-shadow: 0 0 5px #aaa;
    }
    body form button {
        flex: auto;
        height: 30px;
        background-color: green;
        color: white;
        border: none;
        outline: none;
    }
    body form button:hover {
        background-color: lightcoral;
        cursor: pointer;
        box-shadow: 0 0 5px #aaa;
    }
    body a {
        color: #888;
        text-decoration: none;
        margin-top: 15px;
    }
    body a:hover {
        color: lightcoral;
        font-weight: bold;
    }
    
    

    2.3handle.php

    
    
    /**
     *  1.开启会话
     *  2.查看数据
     */
    
    session_start();
    
    $db = new PDO('mysql:host=localhost;dbname=phpedu','root','901026yk');
    $stmt = $db->prepare('select * from user');
    $stmt->execute();
    $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    
    $action = $_GET['action'];
    
    /**
     *
     */
    switch ($action)
    {
        case 'login':
            if($_SERVER['REQUEST_METHOD'] == 'POST') {
                $password = sha1($_POST['password']);
                $email = $_POST['email'];
                $result = array_filter($users, function ($user) use ($password, $email) {
                    return $user['password'] == $password && $user['email'] == $email;
                });
                if (count($result) == 1) {
                    $_SESSION['user'] = serialize(array_pop($result));
                    exit('');
                } else {
                    exit('请求类型错误');
                }
            }
            case 'logout':
                    if (isset($_SESSION['user'])) {
                        session_destroy();
                        exit('');
                    }
                    case 'register':
                        $email= $_POST['email'];
                        $name= $_POST['name'];
                        $password= sha1($_POST['p2']);
                        $register_time = time();
    
                        // 2. sql
                        $sql = <<<SQL
     INSERT `user`
                    SET `name`= ?,
                        `email`= ?,
                        `password`= ?,
                        `register_time`= ?;
    SQL;
    
    
    
                        $stmt = $db->prepare($sql);
                        $data = [$name,$email,$password, $register_time];
                        if ($stmt->execute($data)) {
                            if ($stmt->rowCount() > 0) {
                                // 注册成功之后,让用户自动登录
                                $sql='SELECT * FROM `user` WHERE `id` = ' . $db->lastInsertId();
                                $stmt = $db->prepare($sql);
                                $stmt->execute();
                                $newUser =$stmt->fetch(PDO::FETCH_ASSOC);
                                $_SESSION['user'] = serialize($newUser);
    
                                exit('');
                            } else {
                                exit('');
                            }
                        } else {
                            print_r($stmt->errorInfo());
                        }
    
        // no break
        default:
            exit('参数非法或未定义操作');
    }
    
    /**
     * serialize:序列化数据
     */
    
    • 2.4index.php
    
    
    namespace _0822;
    
    session_start();
    
    // 判断是否已登录?
    if (isset($_SESSION['user'])) {
        $user = unserialize($_SESSION['user']);
    }
    
    
    ?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>用户页面</title>
        <link rel="stylesheet" href="CSS/index.css">
        <style>
    
        </style>
    </head>
    <body>
    <nav>
        <a href="index.php">我的博客</a>
    
        <?php if (isset($user)) : ?>
            <span style="margin-left: 300px"><?=$user['name']?></span>
            <a id="logout">退出</a>
        <?php else: ?>
            <a href="login.php">登录</a>
        <?php endif ?>
    </nav>
    
    
    <script>
        //        为退出按钮创建事件监听器
        document.querySelector('#logout').addEventListener('click', function(event) {
            if (confirm('是否退出')) {
                // 禁用默认行为, 其实就是禁用原标签的点击跳转行为,使用事件中的自定义方法处理
                event.preventDefault();
                // 跳转到退出事件处理器
                window.location.assign('handle.php?action=logout');
            }
        },true);
    </script>
    </body>
    </html>
    
    

    2.5login.php

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>用户登录</title>
        <link rel="stylesheet" type="text/css" href="css/style.css">
    </head>
    
    <body>
    <h3>用户登录</h3>
    <form action="handle.php?action=login" method="post">
        <div>
            <label for="email">邮箱:</label>
            <input type="email" name="email" id="email" placeholder="demo@email.com" required autofocus>
        </div>
    
        <div>
            <label for="password">密码:</label>
            <input type="password" name="password" id="password" placeholder="不少于6位" required>
        </div>
    
        <div>
            <button>提交</button>
        </div>
    </form>
    
    <a href="register.php">还没有帐号, 注册一个吧</a>
    </body>
    
    </html>
    
    

    2.6register.php

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" type="text/css" href="CSS/style.css">
        <title>注册用户title>
    head>
    
    <body>
    <h3>用户注册h3>
    <form action="handle.php?action=register" method="post" onsubmit="return compare()">
        <div>
            <label for="name">呢称:label>
            <input type="text" name="name" id="name" placeholder="不少于3个字符" required autofocus>
        div>
        <div>
            <label for="email">邮箱:label>
            <input type="email" name="email" id="email" placeholder="demo@email.com" required>
        div>
    
        <div>
            <label for="p1">密码:label>
            <input type="password" name="p1" id="p1" placeholder="不少于6位" required>
        div>
    
        <div>
            <label for="p2">重复:label>
            <input type="password" name="p2" id="p2" placeholder="必须与上面一致" required>
        div>
    
        <div>
            <button>提交button><span id="tips" style="color: red">span>
        div>
    form>
    <a href="login.php">我有帐号,直接登录a>
    
    <script>
        // 验证二次密码是否相等?
        function compare() {
            if (document.forms[0].p1.value.trim() !== document.forms[0].p2.value.trim()) {
                document.querySelector('#tips').innerText = '二次密码不相等';
                return false;
            }
        }
    script>
    body>
    
    html>
    
    
    
  • 相关阅读:
    四、分类算法 - 随机森林
    Explain信息中Extra字段解释
    shouldComponentUpdate 是做什么的?
    vite vite.config.js中的配置
    大数据运维一些常见批量操作命令
    文件上传 [GXYCTF2019]BabyUpload1
    Shiro学习之SpringBoot整合
    【c++ primer 笔记】第 16章 模板与泛型编程
    初识设计模式 - 访问者模式
    Gerrit的用法及与gitlab的区别
  • 原文地址:https://blog.csdn.net/qq_53568983/article/details/126957708