Flash数据是一种特别的session数据,它一旦在某个请求中设置后, 只会在下次请求中有效,然后该数据就会自动被删除。 常用于实现只需显示给终端用户一次的信息, 如用户提交一个表单后显示确认信息。

在实际应用中,通过

$session = Yii::$app->session;
$session->setFlash("pwd","123456");
来创建一个flash数据。
$session->getFlash("pwd")
当我们获取其值以后,发现,仅仅第一次获取能获取到,第二次获取就变为空了。
那么其原理是什么呢?我们一起来分析一下:
如果直接点开,getFlash()方法:
public function getFlash($key, $defaultValue = null, $delete = false)
{$counters = $this->get($this->flashParam, []);if (isset($counters[$key])) {$value = $this->get($key, $defaultValue);if ($delete) {$this->removeFlash($key);} elseif ($counters[$key] < 0) {// mark for deletion in the next request$counters[$key] = 1;$_SESSION[$this->flashParam] = $counters;}return $value;} else {return $defaultValue;}
}
    我们会发现,有个默认的$delete参数,但是他是false啊,在if($delete)为假,不会执行removerFlash()啊,可是
为何第二次访问,值就没有了呢,那咱们还得从根源看起。
public function setFlash($key, $value = true, $removeAfterAccess = true)
{$counters = $this->get($this->flashParam, []);$counters[$key] = $removeAfterAccess ? -1 : 0;$_SESSION[$key] = $value;$_SESSION[$this->flashParam] = $counters;
}
    $counters首先执行get方法获取$this->flashParam的值(flashParam在上文有定义)至于为什么要获取他,咱们
下文再说
public $flashParam = '__flash';

    很明显,$removeAfterAccess默认值为真,所以$counters[$key]的值就为-1,然后将value存入session,
然后将"__flash"存入session,其值为-1,即$counters的值。
    然后我们再执行getFlash()方法的时候
public function getFlash($key, $defaultValue = null, $delete = false)
{$counters = $this->get($this->flashParam, []);//从session中获取$counters的值if (isset($counters[$key])) {//是否存在$value = $this->get($key, $defaultValue);//去除session中对应的值if ($delete) {$this->removeFlash($key);} elseif ($counters[$key] < 0) {// mark for deletion in the next request$counters[$key] = 1;$_SESSION[$this->flashParam] = $counters;}return $value;} else {return $defaultValue;}
}
    发现,还是没有执行removeFlash($key),然后思考,这个$counters[$key]是干啥的呢,为什么一直贯穿,为什么
,小于0的时候要改1呢,在我们使用setFlash()方法的时候,记得,他的值被赋值成了-1,于是我们点开$this->get()方法。
public function get($key, $defaultValue = null)
{$this->open();return isset($_SESSION[$key]) ? $_SESSION[$key] : $defaultValue;
}
发现其执行了一个open方法。
public function open()
{if ($this->getIsActive()) {return;}$this->registerSessionHandler();$this->setCookieParamsInternal();@session_start();if ($this->getIsActive()) {Yii::info('Session started', __METHOD__);$this->updateFlashCounters();//更新flash计数} else {$error = error_get_last();$message = isset($error['message']) ? $error['message'] : 'Failed to start session.';Yii::error($message, __METHOD__);}
}
open方法中,有一个updateFlashCounters(),找到其源码
protected function updateFlashCounters()
{$counters = $this->get($this->flashParam, []);if (is_array($counters)) {//如果$counters是一个数组foreach ($counters as $key => $count) {if ($count > 0) {//经行过getFlash()以后,其值变成了1unset($counters[$key], $_SESSION[$key]);} elseif ($count == 0) {$counters[$key]++;}}$_SESSION[$this->flashParam] = $counters;} else {// fix the unexpected problem that flashParam doesn't return an arrayunset($_SESSION[$this->flashParam]);}
}
哎,我们发现,在if($count>0)中,删除了$counters[$kye]和$_SESSION[$key]的值
于是恍然大悟,在第二次getFlash()的之后,由于没有了$counters[$key],所以直接返回了$defaultValue的值,默认为空。
public function getFlash($key, $defaultValue = null, $delete = false)
{$counters = $this->get($this->flashParam, []);//从session中获取$counters的值if (isset($counters[$key])) {//是否存在$value = $this->get($key, $defaultValue);//去除session中对应的值if ($delete) {$this->removeFlash($key);} elseif ($counters[$key] < 0) {// mark for deletion in the next request$counters[$key] = 1;$_SESSION[$this->flashParam] = $counters;}return $value;} else {return $defaultValue;}
}

Yii中Flash数据的处理机制(源码分析)相关推荐

  1. Apache Storm 实时流处理系统通信机制源码分析

    我们今天就来仔细研究一下Apache Storm 2.0.0-SNAPSHOT的通信机制.下面我将从大致思想以及源码分析,然后我们细致分析实时流处理系统中源码通信机制研究. 1. 简介 Worker间 ...

  2. Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法

    Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法 1.spreadOutApp尽量平均分配到每个executor上: 2.非spreadO ...

  3. Linux中mknod命令实现原理以及源码分析

    本篇文章以mknod创建字符设备文件进行讲解 字符设备驱动的Demo例子可参考该篇文章 Linux 编写简单驱动并测试 1. mknod 命令 mknod /dev/hello c 520 0 该命令 ...

  4. java中的==、equals()、hashCode()源码分析(转载)

    在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...

  5. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  6. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析] good

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  7. 集合的get方法中参数从多少开始_源码分析CopyOnWriteArrayList 中的隐藏知识,你Get了吗?...

    欢迎点击 "未读代码" ,关注公众号,文章每周更新 杭州-阿里园区墙 前言 本觉 CopyOnWriteArrayList 过于简单,寻思看名字就能知道内部的实现逻辑,所以没有写这 ...

  8. k8s 驱逐eviction机制源码分析

    原理部分 1. 驱逐概念介绍 kubelet会定期监控node的内存,磁盘,文件系统等资源,当达到指定的阈值后,就会先尝试回收node级别的资源,比如当磁盘资源不足时会删除不同的image,如果仍然在 ...

  9. Android——RIL 机制源码分析

    Android 电话系统框架介绍 在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP.AP与BP之间有两种通信方式: 1. ...

最新文章

  1. M1芯片搞数据科学好使吗?5种基准测试给你答案
  2. Linux【命令】修改文件内容
  3. selectpselect/pollppoll/epoll
  4. C++ Primer 5th笔记(chap 17 标准库特殊设施)匹配标志
  5. java小数点默认定义_java求两个数后小数点默认无限长度
  6. Mybatis入门---一对多、多对多
  7. Python获取文件路径:os.listdir()和os.walk()
  8. optisystem自建matlab信号源仿真
  9. 使用谷歌云盘和colab训练自己的数据集(yolov5格式)
  10. 关于redis HSCAN count参数不生效的问题
  11. Windows XP 32位环境下VS2008+DDKXP驱动开发环境配置
  12. ios 融云 重写对话列表_iOS集成融云SDK即时通讯
  13. 多商家点餐小程序源码
  14. Python PyQt5l表单应用 - 自定义选择下拉框样式
  15. CCF CSP 202104-1
  16. 基于android的影音设计,基于Android的车载影音导航系统软件设计与实现
  17. Python 小白学习之:linux 基础和 python 入门
  18. 封号、扣钱:谁来保证专车司机的利益?
  19. 给定一个由N个非负整数构成的序列,我们来定义一下序列的中位数,如果N是奇数,在对序列排序后,中位数就是最中间的那个数,即排序后,中位数的位置为(N+1)/2,这里序列的位置从1开始。如果N是偶数,则中
  20. 服务器显示中国移动,中国移动服务器地址是什么

热门文章

  1. winform退出/关闭窗体时,弹窗温馨提示
  2. 20230116英语学习
  3. 【数学建模】Day01——层次分析法
  4. tar命令解压时去除目录结构及解压到指定目录
  5. 使用PL/SQL连接Linux下Oracle服务
  6. C++ Primer 第五章 Statements
  7. insmod时候的详细过程
  8. c程序语言捉迷藏,捉迷藏幼儿园小班语言教案
  9. 苹果经典提示音_“今天的不开心就止于此吧”,也可以是你的iPhone充电提示音了...
  10. 防止恶意发广告的人加进QQ群(转)