PHP实战之Session会话控制

精选30+云产品,助力企业轻松上云!>>> hot3.png

  • 目录
  • 1. 前言
  • 2. SESSION的使用
  • 2.1 session简介及工作原理
  • 2.2开启会话session_start()
  • 2.3设置会话$_SESSION
  • 2.4销毁session
  • 3. session实战演示
  • 3.1使用session保存验证码
  • 4.自定义会话管理器
  • 4.1案例:保存session数据到数据库中
  • 4.1.1创建存储数据表
  • 4.1.2存储session接口类
  • 4.1.3测试存储session接口类
  • 5. 总结

1.前言

session是存储在服务端的会话,通过使用session技术,能够很好地帮助我们与客户端进行验证通信,另外,session也是一个高频面试点,因此我们很有必要掌握它。

代码分享:https://github.com/mtdgclub/SeCo

2.SESSION的使用

2.1 session简介及工作原理

会话就是服务器和浏览器保有的共同的小秘密的这段时间.

工作原理如下图所示:

PHP实战之Session会话控制_第1张图片

  • 准备建立会话的时候,PHP会先查看请求是否包含Seesion_id,如果没有服务器会在自己的内存里创建一个新的变量,这个变量就是session_id
  • 服务器会把这个session_id发送到浏览器保存,一般浏览器会把这个ID保存到cookie中
  • 之后浏览器每次再去访问服务器的时候,都会携带cookie中存储的seesion_id,这样服务器就能够认识到对应的客户端
  • 服务器的session_id可以存放任意的会话数据,这些数据是经过序列化的
  • 每个浏览器都能够凭借session_id到服务器认领自己的信息
  • 如果要销毁会话,可以删除会话的数据,销毁会话文件

2.2开启会话session_start()

代码举例:


header('content-type:text/html;charset=utf-8');
//开启会话
session_start();

2.3设置会话$_SESSION

//设置数据
$_SESSION['username']='fangzhijie';
$_SESSION['email']='[email protected]';
$_SESSION['age']=22;

在控制器查看session内容

PHP实战之Session会话控制_第2张图片

可以在php.ini文件查看session配置选项

  • session.save_handler设置用户自定义会话存储函数
  • session.save_path读取/设置当前会话的保存路径
  • session.name读取/设置会话名称,只能由字母数字组成,默认是PHPSESSID
  • session.auto_start设置自动开启session_start(),默认为0不开启
//通过服务器得到session_id的名字
echo 'SESSION的名字:',session_name(),'
';
echo 'SESSION的ID:',session_id(),'
';

up-3232ef9f438ef4cde0fdfb7e0a51e6641ec.png

//使用cookie将session长期保存到客户端
session_start();
$_SESSION['username']='fangzhijie';
$_SESSION['email']='[email protected]';
setcookie(session_name(),session_id(),time()+3600);
  • session.use_cookies指定是否在客户端用cookie来存放会话ID,默认为1(启用)
  • session.user_only_cookies指定是否在客户端仅仅使用cookie来存放会话ID,启用可以防止有关通过URL传递会话ID的攻击,默认是1(启用)
  • session.use_trans_sid指定是否启用透明SID支持,默认为0(禁用)

疑问:

当用户禁用掉cookie,我们的session_id是否可以传递session

分析:

如果我们通过“浏览器->设置->隐私->关闭cookie”会发现,当用户禁用掉cookie情况下是得不到session_id的,那么,这种情况我们如何获取session?

解答:

能够通过URL的形式传递session_id过去

传递代码:



session_start();
$_SESSION['name']='fangzhijie';
$_SESSION['age']='22';
echo "查看信息";

得到代码:



session_id($_GET[session_name()]);
session_start();
print_r($_SESSION);

up-41b9edfbe346cb026e4ddc0a9c617606ccc.png

2.4销毁session

一共有以下三种方法:

  • 将$_SESSION清空,$_SESSION=[]
  • 将cookie中数据清除,setcookie()
  • 销毁会话session_destory()

PS:为了彻底销毁会话,比如在用户退出登录时候,必须同时重置会话ID;如果是通过cookie方式传送会话ID的,那么同时也要调用setcookie()函数删除客户端会话cookie

代码举例:


//初始化,并开启会话
session_start();
//重置所有变量
$_SESSION=array();
//销毁会话中数据,同时销毁会话本身
if(ini_get('session.user_cookies')){
    $params=session_get_cookie_params();
    setcookie(session_name(),'',time()-42000,
        $params['path'],$params['domain'],
        $params['secure'],$params['httponly']
    );
}
//最后,销毁会话
session_destroy();

3. session实战演示

3.1使用session保存验证码



/**

 * 产生验证码

 * @param int $type 类型0纯数字 1字母 2数字+字母

 * @param int $length 长度

 * @param int $width 宽度

 * @param int $height 高度

 * @return string 真实验证码字符串

 */

function generateVerity($type = 0, $length = 4, $width = 100, $height = 30)

{

    //创建黑色画布

    $image = imagecreatetruecolor($width, $height);

    //定义画布背景色

    $bgcolor = imagecolorallocate($image, 255, 255, 255);

    //填充颜色

    imagefill($image, 0, 0, $bgcolor);


    $str = '';

    $captcha = "";

    switch ($type) {

        case 0:

            $str = join('', array_rand(range(0, 9), $length));

            break;

        case 1:

            $str = join('', array_rand(array_flip(array_merge(range('a', 'z'), range('A', 'Z'))), $length));

            break;

        case 2:

            $str = join('', array_rand(array_flip(array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'))), $length));

            break;

    }

    

    for ($i = 0; $i < $length; $i++) {

        // 字体大小

        $fontsize = 10;

        // 字体颜色

        $fontcolor = randColor($image);

        $captcha .= $fontcontent = $str;

        // 显示的坐标

        $x = ($i * 100 / 4) + mt_rand(5, 10);

        $y = mt_rand(5, 10);

        // 填充内容到画布中

        imagestring($image, $fontsize, $x, $y, $fontcontent, $fontcolor);

    }


    //4.3 设置背景干扰元素

    for ($$i = 0; $i < 200; $i++) {

        $pointcolor = imagecolorallocate($image, mt_rand(50, 200), mt_rand(50, 200), mt_rand(50, 200));

        imagesetpixel($image, mt_rand(1, 99), mt_rand(1, 29), $pointcolor);

    }


    //4.4 设置干扰线

    for ($i = 0; $i < 3; $i++) {

        $linecolor = imagecolorallocate($image, mt_rand(50, 200), mt_rand(50, 200), mt_rand(50, 200));

        imageline($image, mt_rand(1, 99), mt_rand(1, 29), mt_rand(1, 99), mt_rand(1, 29), $linecolor);

    }


    header('Content-Type:image/png');

    imagepng($image);

    imagedestroy($image);

    return $captcha;

}


function randColor($image)

{

    //字体颜色

    return imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));

}


//调用

session_start();

$_SESSION['verityCode'] = generateVerity();

PHP实战之Session会话控制_第3张图片

4.自定义会话管理器

如果访问用户有千万级别,而seesion还是设置文件形式保存,那么就会产生千万数量的session文件,访问速度就很慢,那么此时我们可以改变存储的形式;我们可以改为存储到数据库,但是数据库访问量大了,还是不可取;因此又可保存到非关系数据库

4.1案例:保存session数据到数据库中

首先,需要使用自定义处理器,比如让数据库自定义为user

session.save_hander定义存储和获取与绘画关联的数据处理器名字

4.1.1创建存储数据表

CREATE TABLE `NewTable` (

`session_id`  char(40) NOT NULL ,

`session_data`  varchar(200) NULL ,

`session_expires`  int(11) NULL ,

PRIMARY KEY (`session_id`)

)

ENGINE=InnoDB

DEFAULT CHARACTER SET=utf8

;

4.1.2存储session接口类

    public function write($session_id, $session_data)

    {

        $newExp = time() + $this->lifetime;

        $session_id = mysqli_escape_string($this->link, $session_id);

        //查询是否存在,存在则更新;否则则写入

        $sql = "

        SELECT * FROM sessions WHERE id ={$session_id}

        ";

        $result = mysqli_query($this->link, $sql);

        if (mysqli_num_rows($result) == 1) {

            //更新操作

            $sql = "";

        } else {

            //新增操作

            $sql = "";

        }

        $result = mysqli_query($this->link, $sql);

        return mysqli_affected_rows($this->link) == 1;

    }


    public function read($session_id){

        $session_id = mysqli_escape_string($this->link, $session_id);

        $time = time();

        $sql = "

        SELECT * FROM sessions WHERE id ={$session_id} AND session_expires <{$time}

        ";

        $result = mysqli_query($this->link, $sql);

        if(mysqli_num_rows($result)==1){

            return mysqli_fetch_assoc($result)['session_data'];

        }else{

            return '';

        }

    }

4.1.3测试存储session接口类



require_once 'session.class.php';

$sessionClass = new session();

ini_set('session.save_handler','user');

session_set_save_handler($sessionClass,true);

session_start();

$_SESSION['username'] = 'fangzhijie';

$_SESSION['age'] = 23;

$_SESSION['contract'] = 'this is a test';

$_SESSION['email'] = '[email protected]';


//打印

var_dump($_SESSION);

//清空

session_destroy();

5.总结

通过本章简要的总结和掌握了session相关的技术和知识点,如果想要更加深入了解,能够先学习http相关的知识点,这样对session和cookie的理解就更加渗透。

你可能感兴趣的:(数据库,python,java,mysql,session)