addFlash()的内容不能被正常销毁 [ 未指定版本 ]
正常情况下addFlash()添加的内容会在getFlash()之后被销毁,然而这两天在将 YII_ENV 参数配置为 prod(web/index.php : defined('YII_ENV') or define('YII_ENV', 'prod');)
之后发现自动销毁失效,添加的内容会一直存在,后来逐步检查,进一步发现是问题出在config/web.php:
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
#'password' => 'gii',
'allowedIPs' => ['127.0.0.1', '10.0.0.*', '*.*.*.*'] // 按需调整这里
];
}
prod模式下没有加载debug模块,在手动加载debug模块之后,flash的销毁恢复正常。
即 启用这两行代码:
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
找了半天没发现debug module 和 flsah,session之间有什么关系,不理解,不科学,故求助各位~~
最佳答案
-
flash
内容存储在session
中, 和debug module
没什么关系.addFlash('a', 'b')
之后, 再getFlash('a')
之后, 是可以销毁这条消息.但是 : 是在下次请求中销毁, 本次请求的后续处理中还存在.
共 11 条回复@500miles
额,不好意思我记错了,getFlash()时置delete=true 或是调用$session->removeFlash()都是有效的。但是除此之外的自动销毁还是无效。刚才写了下测试:
actions:public function actionTestFlash() { Yii::$app->session->setFlash('delete when access', 'hello world', true); Yii::$app->session->setFlash('delete when next call', 'hello world', false); Yii::$app->session->setFlash('set delete when getFlash', 'hello world'); Yii::$app->session->setFlash('set nothing, wait for auto delete in the next call', 'hello world'); } public function actionNewCall1() { return $this->render('new_call1'); } public function actionNewCall2() { return $this->render('new_call2'); }
new_call1.php:
$session = Yii::$app->session; var_dump('delete when access' . ' - ' . $session->getFlash('delete when access')); var_dump('delete when next call' . ' - ' . $session->getFlash('delete when next call')); var_dump('set delete when getFlash' . ' - ' . $session->getFlash('set delete when getFlash', null, true)); var_dump('set nothing, wait for auto delete in the next call' . ' - ' . $session->getFlash('set nothing, wait for auto delete in the next call')); var_dump($_SESSION);
new_call2.php:
$session = Yii::$app->session; $flashes = $session->getAllFlashes(); var_dump($flashes); var_dump($_SESSION); $session->removeAllFlashes();
new-call1的输出:
string(32) "delete when access - hello world" string(35) "delete when next call - hello world" string(38) "set delete when getFlash - hello world" string(64) "set nothing, wait for auto delete in the next call - hello world" array(4) { ["delete when access"]=> string(11) "hello world" ["__flash"]=> array(3) { ["delete when access"]=> int(1) ["delete when next call"]=> int(0) ["set nothing, wait for auto delete in the next call"]=> int(1) } ["delete when next call"]=> string(11) "hello world" ["set nothing, wait for auto delete in the next call"]=> string(11) "hello world" }
new_call2输出:
array(3) { ["delete when access"]=> string(11) "hello world" ["delete when next call"]=> string(11) "hello world" ["set nothing, wait for auto delete in the next call"]=> string(11) "hello world" } array(4) { ["delete when access"]=> string(11) "hello world" ["__flash"]=> array(3) { ["delete when access"]=> int(1) ["delete when next call"]=> int(0) ["set nothing, wait for auto delete in the next call"]=> int(1) } ["delete when next call"]=> string(11) "hello world" ["set nothing, wait for auto delete in the next call"]=> string(11) "hello world" }
除了在getFlash()时设置delete=true的那次之外其余三次均没有正常销毁,当然,removeAllFlashes()之后整个世界都清净了。
@sabersma 大概找到原因了。。推测是因为Yii入口脚本我使用
session_start()
开启session而不是使用Yii::$app->session->open()
方式开启,public function open() { if ($this->getIsActive()) { return; } $this->registerSessionHandler(); $this->setCookieParamsInternal(); @session_start(); if ($this->getIsActive()) { Yii::info('Session started', __METHOD__); $this->updateFlashCounters(); } else { $error = error_get_last(); $message = isset($error['message']) ? $error['message'] : 'Failed to start session.'; Yii::error($message, __METHOD__); } }
所以导致open()在调用时,判断到session已开启直接返回,没有执行后续的updateFlashCounters()方法进行清理,感觉这里的代码,,嗯。有点不太。。机智?
luoxiao 觉得很赞
其他 1 个回答
-
imyiligege 回答于 2018-01-23 11:37 举报
在vendor\yiisoft\yii2\web\Session.php中是有两处调用$this->updateFlashCounters();的,我在慕课网看的yii电商教程老师给的代码少了一行,就导致getFlash一直能够获取值
sabersma
最后登录:2017-10-11
在线时长:1小时8分
- 粉丝0
- 金钱85
- 威望0
- 积分95