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. 20张图助你了解JVM运行时数据区,你还觉得枯燥吗?
  2. 【Android基础】 Launch Mode
  3. java布道师_初探第10代Java帝国:11位Java专家道出了他们最喜欢的功能
  4. Linux运维 第三阶段 (二) DHCP
  5. kali之metasploit基本使用
  6. 程序员如何巧妙学习算法技巧?
  7. c/c++ 时间函数总结 linux
  8. QSqlTableModel配合QTableView设置单元格对齐方式和前景色等
  9. python循环语句输出_python循环语句
  10. python库手册(官方)python文档
  11. python源码打包成exe、exe反编译、pyd加密防止反编译
  12. Excel/WPS之粘贴可见内容
  13. OCR文本检测模型—CTPN
  14. 堪萨斯州立大学计算机科学,2020年堪萨斯州立大学排名TFE Times美国最佳计算机科学硕士专业排名第99...
  15. 三只松鼠网络营销成功之路
  16. 蓝牙RFCOMM协议
  17. 交通强国,标准先行【附PPT】
  18. 如何利用小红书进行产品营销?小红书营销技巧有哪些?
  19. 河南工业大学高级JAVA实验,大学_计算机控制技术实验报告河南工业大学4
  20. EXCEL列乱序后内容重新对应

热门文章

  1. 课题相关自主学习——小学数学中高年级计算错误的原因分析及对策
  2. 红黑树原理及java实现
  3. SQL约束之外键约束
  4. 微信小程序开发(笔记)
  5. 【 Threejs 】- Shader 着色器实例渲染教程
  6. Android 多用户 —— 从入门到应用分身
  7. input标签readonly属性
  8. Oracle---启动与关闭数据库实例
  9. 强化学习在推荐系统中的环境模拟器构建
  10. 内存映射文件的方式进行进程间通信