JellyBool

17773 经验值

应该不可以,你要使用的话,得看完背后的所有相关的改动。

看 laravel.log 就应该可以了吧。默认在 storage 目录下

file_put_contents(/data/www/operate/storage/framework/cache/db/13/db137b150629648c2faa340de41256492a2476ea): failed to open stream: No such file or directory

并没有这个文件

.gitignore 文件里面声明,把这两个默认都 ignore 了

app.php 下,使用 providers 的这个类:

Illuminate\Session\SessionServiceProvider::class,

点开,看到 register() 方法:

public function register()
    {
        $this->registerSessionManager();

        $this->registerSessionDriver();

        $this->app->singleton('Illuminate\Session\Middleware\StartSession');
    }

也就是最后使用到的是:Illuminate\Session\Middleware\StartSession,这个类中有个 handle() 方法:

 public function handle($request, Closure $next)
    {
        $this->sessionHandled = true;

        // If a session driver has been configured, we will need to start the session here
        // so that the data is ready for an application. Note that the Laravel sessions
        // do not make use of PHP "native" sessions in any way since they are crappy.
        if ($this->sessionConfigured()) {
            $session = $this->startSession($request);

            $request->setSession($session);
        }

        $response = $next($request);

        // Again, if the session has been configured we will need to close out the session
        // so that the attributes may be persisted to some storage medium. We will also
        // add the session identifier cookie to the application response headers now.
        if ($this->sessionConfigured()) {
            $this->storeCurrentUrl($request, $session);

            $this->collectGarbage($session);

            $this->addCookieToResponse($response, $session);
        }

        return $response;
    }

这里就是一个 middleware 的设计思想,在其中的$this->startSession中获取Session的方法是getSession():

$session = $this->manager->driver();

这里面的$this->manager通过依赖注入,注入的类是Illuminate\Session\SessionManager,也就是在这里调用了SessionManagerdriver() 方法。而 driver() 方法位于 SessionManager 的父类 Manager中,具体是这个样子的:

public function driver($driver = null)
    {
        $driver = $driver ?: $this->getDefaultDriver();

        // If the given driver has not been created before, we will create the instances
        // here and cache it so we can return it next time very quickly. If there is
        // already a driver created by this name, we'll just return that instance.
        if (! isset($this->drivers[$driver])) {
            $this->drivers[$driver] = $this->createDriver($driver);
        }

        return $this->drivers[$driver];
    }

在这里调用 getDefaultDriver()方法,又回到了Illuminate\Session\SessionManager 类中,代码如下:

  public function getDefaultDriver()
    {
        return $this->app['config']['session.driver'];
    }

到这里就很清晰咯,就是我们在 app/config/session.php 中定义的driver配置项,获取这个配置后,我们可以从 createDriver()的源码看到,它实际上是调用 createXXXXDriver() 的方式获取到driver的。。

protected function createDriver($driver)
    {
        
    $method = 'create'.Str::studly($driver).'Driver';

        // We'll check to see if a creator method exists for the given driver. If not we
        // will check for a custom driver creator, which allows developers to create
        // drivers using their own customized driver creator Closure to create it.
        if (isset($this->customCreators[$driver])) {
            return $this->callCustomCreator($driver);
        } elseif (method_exists($this, $method)) {
            return $this->$method();
        }

        throw new InvalidArgumentException("Driver [$driver] not supported.");
    }

比如你配置 app/config/session.php 为 file,也就是 createFileDriver() 。有了 driver 之后,最后通过 buildSession() 创建 session

protected function buildSession($handler)
{
    if ($this->app['config']['session.encrypt']) {
        return new EncryptedStore(
            $this->app['config']['session.cookie'], $handler, $this->app['encrypter']
        );
    } else {
        return new Store($this->app['config']['session.cookie'], $handler);
    }
}

然后回到 StartSession 这个类,我们再看 getSession() 这个方法:

$session->setId($request->cookies->get($session->getName()));

这里就根据 cookies 来设置不同的 sessionkey。这里就创建完 session 了,如何获取 session 的数据呢?依然是在 StartSession 类的 startSession() 方法这里有一句:

$session->start();

点开,看看源码,这个源码位于 Illuminate\Session\Store中,可以从上面 的 buildSession()new EncryptedStore() 追踪

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

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

        return $this->started = true;
    }

这里执行下面的 $this->loadSession()

  protected function loadSession()
    {
        $this->attributes = array_merge($this->attributes, $this->readFromHandler());

        foreach (array_merge($this->bags, [$this->metaBag]) as $bag) {
            $this->initializeLocalBag($bag);

            $bag->initialize($this->bagData[$bag->getStorageKey()]);
        }
    }

loadSession() 又执行下面的 $this->readFromHandler()

protected function readFromHandler()
    {
        $data = $this->handler->read($this->getId());

        if ($data) {
            $data = @unserialize($this->prepareForUnserialize($data));

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

        return [];
    }

handler 中调用了 read() 方法,这里的 handler 是一个接口 SessionHandlerInterface $handler ,也就是我们预先定义的各种 handler中读取数据,比如说 app/config/session.phpfile 就是 FileSessionHandler,这里就有 read() 方法:

  public function read($sessionId)
    {
        if ($this->files->exists($path = $this->path.'/'.$sessionId)) {
            if (filemtime($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
                return $this->files->get($path);
            }
        }

        return '';
    }

到这里,流程就OK了。

呃,这样看来不是好好的么?。。。。。。。

你试过这个没有?

@foreach($discussion->comments() as $comment)