PHP中session机制解析

更新日期: 2019-06-15阅读: 1.9k标签: 机制

一、php的默认session机制

php默认用磁盘文件来实现session
在php.ini中session.save_handler = files定义session机制
session.save_path="D:\dev\xampp\tmp" 定义session的存储位置

1.1、启动session
session_start()。
sesson_start()函数是启动session的开始,session默认存放在文件中,且具有一定概率触发session的垃圾回收机制。
php自身的垃圾回收对session是无效的,因为默认session是存放在文件中的。
session的垃圾回收概率是根据
session.gc_probability =1
session.gc_divisor =1000
session.gc_maxlifetime =1440//过期时间 默认24分钟
这三个参数去计算的。
计算规则为:
触发概率 = session.gc_probability / session.gc_divisor; 结果 1/1000, 

1.2、配置session.save_path
session.save_path在php.ini中提供了不同的配置方式:

session.save_path="D:\dev\xampp\tmp"
session.save_path="N;D:\dev\xampp\tmp"

其中N为正整数,表示目录分级存放:
若N=2,假设此时sessionId为 63f2k77g4r0ls06g3p93t0cpkd
那么,session信息的存放格式为:D:\dev\xampp\tmp\6\3\sess_63f2k77g4r0ls06g3p93t0cpkd
使用分级存放时,session的垃圾回收机制将会无效,需要自己写脚本处理过期session文件。
且子目录php不会自己创建,需要手动去创建6/3/目录。
如果分2级存放,可以通过脚本去事先创建好:

function createSessionDir ()
{
    $basePath = trim(explode(‘;‘, session_save_path())[1], ‘/\\‘);
    $str = ‘0123456789abcdefghijklmnopqrstuvwxyz‘;
    $len = strlen($str);
    for ($i = 0; $i < $len; $i++) {
        for ($j = 0; $j < $len; $j++) {
            $path = $basePath . DIRECTORY_SEPARATOR . $str[$i] . DIRECTORY_SEPARATOR . $str[$j];
            if (!@file_exists($path)) {
                mkdir($basePath . DIRECTORY_SEPARATOR . $str[$i] . DIRECTORY_SEPARATOR . $str[$j]);
            }

        }
    }
}


1.3、sessionId
$_COOKIE[session_name()];中存放了当前session的sessionId信息。其中session_name()取的是php.ini中的session.name = PHPSESSID 的值。如果不存在会生成一个sessionId,然后将id作为cookie的值传递到客户端。
相当于执行setcookie()函数:

setcookie(session_name(),
    session_id(),
    session.cookie_lifetime,//默认0
    session.cookie_path,//默认‘/‘,当前程序跟目录下都有效
    session.cookie_domain,//默认为空
)

按照php手册里的说明,使用setcookie()之前不能有任何输出,但是我测试时,在函数之前echo了内容是不会报错的。
原因是php5.3版本以下时,php.ini有一项配置output_buffering,此配置项,在php5.3以下是默认为0,在5.3以上则默认是4096。
因为使用的版本大于5.3,所以在测试的时候,默认是开启output_buffering的。
开启output_buffering的时候,无论是echo,还是var_dump,print_r,任何输出,都会在php脚本结束时,统一随着http响应返回给客户端,(超过4096大小时,可能会分段返回)。所以不会报错。

1.4、session赋值
添加一个session值:$_SESSION[‘name]=‘zahngsan‘,此时这个值会在内存中存在,当脚本执行完毕时,会将其写入到指定sessionId的文件中,然后关闭资源。
如网页的匿名用户存在一个session,当登录后需要更换session:

//删除旧的session信息
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), ‘‘, time() - 86400);
}
session_regenerate_id();//重新生成sessionId


1.5、销毁session信息
cookie中携带的session信息为即时cookie,保存在浏览器中,当浏览器关闭后,才会过期。
但是一般我们在用户退出登录时,就需要销毁其cookie和session信息,销毁的方式:

a、setcookie(session_name(), session_id(), time() - 86400);//退出登录前执行
b、unset($_SESSION);//会删除所有的$_SESSION数据,刷新后,有COOKIE传过来,但是没有数据
c、session_destroy();//彻底删除$_SESSION并删除session文件和sessionId

当不关闭浏览器的情况下,再次刷新,b和c都会有COOKIE传过来,但是找不到数据。


二、用户自定义处理机制
php.ini中配置session.save_handler = user 就会触发自定义处理机制其中user字符是随意的,不固定。
自 PHP 5.4 开始,可以使用下面的方式来注册自定义会话存储函数:
session_set_save_handler ( object $sessionhandler [, bool $register_shutdown = TRUE ] ) : bool
sessionhandler为实现了 SessionHandlerInterface接口的对象

MySession.php
<?php
/**
 * Desc: 自定义session处理机制,>5.4
 * Class: Session
 * User: zb
 * Date: 2019/6/14 18:32
 */

class MySession implements SessionHandlerInterface
{
    private $savePath;

    public function close ()
    {
        return true;
    }

    public function destroy ($sessionId)
    {
        $file = $this->savePath . ‘/sess_‘ . $sessionId;
        if (file_exists($file)) {
            @unlink($file);
        }
        return true;
    }

    public function gc ($maxlifetime)
    {
        $sessionFiles = glob($this->savePath . ‘/sess_*‘);
        foreach ($sessionFiles as $file) {
            if (file_exists($file) && filemtime($file) + $maxlifetime < time()) {
                @unlink($file);
            }
        }
        return true;
    }

    public function open ($savePath, $sessionName)
    {
        $this->savePath = $savePath;
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath, 0777);
        }

        return true;
    }

    public function read ($sessionId)
    {
        return (string)@file_get_contents($this->savePath . ‘/sess_‘ . $sessionId);
    }

    public function write ($sessionId, $sessionData)
    {
        return @file_put_contents($this->savePath . ‘/sess_‘ . $sessionId, $sessionData) === false ? false : true;
    }
}

使用自定义session机制:

index.php
<?php
/**
 * Desc: xxx
 * User: zb
 * Date: 2019/6/14 18:32
 */
include ‘MySession.php‘;
$mySession = new MySession();
session_set_save_handler($mySession, true);
session_start();
if (!empty($_GET) && $_GET[‘user‘] && $_GET[‘passwd‘]) {
    $_SESSION[‘user‘] = $_GET[‘user‘];
    $_SESSION[‘passwd‘] = $_GET[‘passwd‘];
    printInfo($_SESSION, ‘allSessionData‘);
    printInfo($_COOKIE[session_name()], ‘sessionId‘);
} else {
    printInfo(‘get无数据‘);
}

function printInfo ($val, $key = ‘‘)
{
    header(‘Content-Type‘, ‘text/html; charset=UTF-8‘);
    $val = var_export($val, true);
    if ($key) {
        $val = $key . ‘ => ‘ . $val;
    }
    echo $val;
    echo "<br>";
}

链接: https://www.fly63.com/article/detial/3719

浅析前端页面渲染机制

作为一个前端开发,最常见的运行环境应该是浏览器吧,为了更好的通过浏览器把优秀的产品带给用户,也为了更好的发展自己的前端职业之路,有必要了解从我们在浏览器地址栏输入网址到看到页面这期间浏览器是如何进行工作的

这一次,彻底弄懂 JavaScript 执行机制

javascript是一门单线程语言,Event Loop是javascript的执行机制.牢牢把握两个基本点,以认真学习javascript为中心,早日实现成为前端高手的伟大梦想!

创建js hook钩子_js中的钩子机制与实现

钩子机制也叫hook机制,或者你可以把它理解成一种匹配机制,就是我们在代码中设置一些钩子,然后程序执行时自动去匹配这些钩子;这样做的好处就是提高了程序的执行效率,减少了if else 的使用同事优化代码结构

小程序的更新机制_如何实现强制更新?

在讲小程序的更新机制之前,我们需要先了解小程序的2种启动模式,分别为:冷启动和热启动。小程序不同的启动方式,对应的更新情况不不一样的。无论冷启动,还是热启动。小程序都不会马上更新的,如果我们需要强制更新,需要如何实现呢?

基于JWT的Token认证机制实现及安全问题

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。其JWT的组成:一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

web前端-JavaScript的运行机制

本文介绍JavaScript运行机制,JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。

轮询机制解决后端任务回调问题

现在有一个需求,前端有一个按钮,点击以后会调用后端一个接口,这个接口会根据用户的筛选条件去hadoop上跑任务,将图片的base64转为img然后打包成zip,生成一个下载连接返回给前端,弹出下载框。hadoop上的这个任务耗时比较久

JavaScript预解释是一种毫无节操的机制

js代码执行之前,浏览器首先会默认的把所有带var和function的进行提前的声明或者定义:1.理解声明和定义、2.对于带var和function关键字的在预解释的时候操作不一样的、3.预解释只发生在当前的作用域下

js对代码解析机制

脚本执行js引擎都做了什么呢?1.语法分析 2.预编译 3.解释执行。在执行代码前,还有两个步骤;语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误 ,查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined

web认证机制

以前对认证这方面的认识一直不太深刻,不清楚为什么需要token这种认证,为什么不简单使用session存储用户登录信息等。最近读了几篇大牛的博客才对认证机制方面有了进一步了解。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!