laravel为什么设置session后会出现这种情况?

查看:325
本文介绍了laravel为什么设置session后会出现这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

在父类控制器的构造函数里面这样设置一个session后

 class CommonController extends Controller
    {  
       public function __construct(){
          Session::put('name','aaa');
       }
    }



    class LoginController extends CommonController
    {   
        public function login(Request $request){
                echo Session::get('name');
                return view('login');
        }
    }

然后在子类的控制器里面这样输出这个session 这样可以正常输出aaa 但是当我把父类的name值改成bbb后刷新login页面这时候输出的还是aaa 这是为什么呢?这时候应该是bbb才对呀 在TP中这样没问题 但是在laravel中不知道为什么会这样?

解决方案

这个可以在源码中得到解答,原则上在构造函数中不要操作Session,因为那个时候大部分情况下,Session 还没有启动,为了方便描述,分别在代码中加入代码:

<?php

namespace App\Http\Controllers;

class CommonController extends Controller
{  
   public function __construct(){
      \Session::put('name','aaa');
      var_dump(\Session::isStarted());
   }
}

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class LoginController extends CommonController
{   
    public function login(Request $request){
        echo \Session::get('name');
        var_dump(\Session::isStarted());
    }
}

如果你运行,会看到输出,第一个isStarted为false, 第二个为true。

那么,我们看一下Laravel启动Session的时候做了些什么。

Illuminate\Session\Store 摘取代码

public function start()
{
    $this->loadSession();

    if (! $this->has('_token')) {
        $this->regenerateToken();
    }

    return $this->started = true;
}

/**
 * Load the session data from the handler.
 *
 * @return void
 */
protected function loadSession()
{
    $this->attributes = array_merge($this->attributes, $this->readFromHandler());
}

/**
 * Read the session data from the handler.
 *
 * @return array
 */
protected function readFromHandler()
{
    if ($data = $this->handler->read($this->getId())) {
        $data = @unserialize($this->prepareForUnserialize($data));

        if ($data !== false && ! is_null($data) && is_array($data)) {
            return $data;
        }
    }

    return [];
}

我们可以看到,在session启动的时候,会用上次落地的session存储覆盖类本身的attributes属性中的值,那么回归你的问题:

  1. 当你在构造函数中put的时候,这个值被写到了,$this->attributes['name']

  2. Session启动的时候拿本地session数据中name覆盖了 $this->attributes['name']

  3. 为什么本地有这个name,因为第一次的时候被写入了存储

验证一下逻辑,你可以设置另外的key试试看,肯定没有问题的,比如

//CommonController.php
\Session::put('name1','bbb');
//LoginControoler.php
\Session::get('name1');

综上所述,

  • 探索源码方知究竟

  • 避免在控制器的构造函数中直接使用Session

这篇关于laravel为什么设置session后会出现这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆