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

Laravel - storing into session from service provider?

我正在使用 GeoIP 包来获取用户的 IP 并将其转换为邮政编码。我不想为用户发出的每个请求都这样做,而是一次性将 IP 发送到邮政编码,将其存储到会话中,然后当我需要使用它时,只需检查会话中是否存在邮政编码。

我试图将代码放在 AppServiceProvider@boot 中,但它不起作用。它不会被记住到会话中。我尝试了内部路线但效果不佳。

编辑
appserviceprovider的boot方法里面的代码。这只是一个测试。

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

问题是每次都会运行,因为邮政编码没有保存在会话中。到目前为止,在我的测试中 if 永远不会为假。

我需要在哪里放置代码以将邮政编码存储到会话中,并且即使用户未登录也能记住它?

我基本上需要这样的东西:
1- 用户第一次访问服务器上的页面(任意页面)
2- 我获取用户 IP 并将其转换为邮政编码
3- 我将邮政编码存储到会话中
4-对于用户发出的每个其他请求,我检查会话中是否存在邮政编码。如果不是我执行步骤 2.
5- 将邮政编码用于其用途

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

在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);
    }
}

在会话中存储邮政编码后,您可以直接从会话中的控制器访问它,或者,您可以在中间件中实例化一个 class 并稍后重新访问它:

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

通过这种方式,您可以在控制器中自动注入 ZipClass 依赖关系,并且 Laravel 将返回您之前在中间件

中构建的 $zipClass 实例