Laravel - 从服务提供商存储到会话中?

时间:2015-12-11 04:25:30

标签: php laravel session laravel-5 service-provider

我正在使用GeoIP软件包来获取用户的IP并将其翻译成邮政编码。我不想为用户正在进行的每个请求执行此操作,而是执行一次IP转码,将其存储到会话中,然后当我需要使用它时,只检查会话中是否存在zipcode。

我尝试将代码放在AppServiceProvider @ boot中,但它不起作用。会议中没有记住它。我尝试了内部路线,但没有工作。

修改
appserviceprovider的boot方法内的代码。这只是一个考验。

If (! Session()->has ('zipcode'))
    Session(['zipcode' => geocodeZipcode()]);

问题在于,每次都会运行,因为会话中不会保留zipcode。到目前为止,我的测试中的if永远不会是假的。

即使用户未登录,我还需要将代码存储在会话中并将其记住?

我基本上需要这样的东西:
1-用户首次访问服务器上的页面(任何页面)
2-我得到用户IP并将其翻译成邮政编码
3-我将邮政编码存储到会话中 4-对于每个其他请求,用户让我检查会话中是否存在zipcode。如果不是,我执行步骤2.
5-将zipcode用于其目的

我应该在哪里放置第2步和第3步?

1 个答案:

答案 0 :(得分:1)

在Laravel中,会话通过中间件初始化,所有中间件在服务提供商启动阶段后执行

这就是您在服务提供商中无法访问会话的原因:它尚未初始化

您应该将步骤2和3放在中间件中:

class ZipCodeMiddleware
{
    public function handle( Request $request, Closure $next )
    {
        //ZIP CODE NOT FOUND IN SESSION: CREATE IT AND STORE
        if ( ! Session::has( 'zipcode' ) )
        {
            //get ip and translate to zip     
            //store zip in the session
        }    

        //use zip code here or access it later from Session

        return $next($request);
    }
}

一旦您将邮政编码存储在会话中,您就可以直接从会话中从控制器访问它,或者,您可以在中间件中实例化一个类,然后使用以下命令重新访问它:

 //use zip code here or access it later from Session
 $zipClass = new ZipClass( $zipCode );
 App::instance( ZipClass::class, $zipClass );

通过这种方式,您可以在控制器中自动注入ZipClass依赖性,Laravel将为您提供先前在中间件中构建的$zipClass实例