使用服务提供商的中间件获取覆盖的配置
Get overridden config with Middleware from Service Provider
我在服务容器中绑定 Class 时遇到问题。这是我的路线。
Route::group(['middleware' => 'partner', 'domain' => '{partner}.example.com'], function() {
$firebaseClient = app('App\Services\FirebaseClient');
$firebaseClient->pushData('users.json', ['name' => 'Risal Ganteng']);
});
这是我用于绑定 FirebaseClient 的自定义服务提供商。
class FirebaseClientServiceProvider extends ServiceProvider
{
/**
* Register FirebaseClient class with the Laravel IoC container.
*
* @return void
*/
public function register()
{
$this->app->bind(\App\Services\FirebaseClient::class, function($app)
{
$config = $app['config'];
$options = [
'api_version' => $config['services.firebase.api_version']
];
return new \App\Services\FirebaseClient($config['services.firebase.database_url'], $options);
});
}
}
这是我的自定义路由中间件,用于覆盖基于子域的配置 services.firebase。
class PartnerMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$partner_id = $request->route('partner');
$partner = Partner::findOrFail($partner_id);
// set config
config([
'services.firebase.api_key' => $partner->firebase_api_key,
'services.firebase.auth_domain' => $partner->firebase_auth_domain,
'services.firebase.database_url' => $partner->firebase_database_url,
]);
return $next($request);
}
}
问题是,当我尝试在 FirebaseServiceProvider 中获取配置时,配置 services.firebase.* 值为空,因为 ServiceProvider 在路由中间件之前注册。
以及如何解决这个问题?
谢谢。
好吧,中间件的执行时间比您的服务提供商晚得多,因此重写配置无效。您必须在 更改配置后 绑定您的服务。
为什么不将绑定移动到中间件?只需从 register() 复制粘贴整个块并将其放在中间件中的 config() 之后。
或者,您可以在 config() 之后将 Firebase 客户端附加到中间件中的 Request 对象,而不是通过服务容器解析。
您不应在 config/app.php
文件中注册您的服务提供商。在 PartnerMiddleware
中间件中动态注册 FirebaseClientServiceProvider
提供程序。
class PartnerMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$partner_id = $request->route('partner');
$partner = Partner::findOrFail($partner_id);
// set config
config([
'services.firebase.api_key' => $partner->firebase_api_key,
'services.firebase.auth_domain' => $partner->firebase_auth_domain,
'services.firebase.database_url' => $partner->firebase_database_url,
]);
app()->register(FirebaseClientServiceProvider::class);
return $next($request);
}
}
我在服务容器中绑定 Class 时遇到问题。这是我的路线。
Route::group(['middleware' => 'partner', 'domain' => '{partner}.example.com'], function() {
$firebaseClient = app('App\Services\FirebaseClient');
$firebaseClient->pushData('users.json', ['name' => 'Risal Ganteng']);
});
这是我用于绑定 FirebaseClient 的自定义服务提供商。
class FirebaseClientServiceProvider extends ServiceProvider
{
/**
* Register FirebaseClient class with the Laravel IoC container.
*
* @return void
*/
public function register()
{
$this->app->bind(\App\Services\FirebaseClient::class, function($app)
{
$config = $app['config'];
$options = [
'api_version' => $config['services.firebase.api_version']
];
return new \App\Services\FirebaseClient($config['services.firebase.database_url'], $options);
});
}
}
这是我的自定义路由中间件,用于覆盖基于子域的配置 services.firebase。
class PartnerMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$partner_id = $request->route('partner');
$partner = Partner::findOrFail($partner_id);
// set config
config([
'services.firebase.api_key' => $partner->firebase_api_key,
'services.firebase.auth_domain' => $partner->firebase_auth_domain,
'services.firebase.database_url' => $partner->firebase_database_url,
]);
return $next($request);
}
}
问题是,当我尝试在 FirebaseServiceProvider 中获取配置时,配置 services.firebase.* 值为空,因为 ServiceProvider 在路由中间件之前注册。
以及如何解决这个问题?
谢谢。
好吧,中间件的执行时间比您的服务提供商晚得多,因此重写配置无效。您必须在 更改配置后 绑定您的服务。
为什么不将绑定移动到中间件?只需从 register() 复制粘贴整个块并将其放在中间件中的 config() 之后。
或者,您可以在 config() 之后将 Firebase 客户端附加到中间件中的 Request 对象,而不是通过服务容器解析。
您不应在 config/app.php
文件中注册您的服务提供商。在 PartnerMiddleware
中间件中动态注册 FirebaseClientServiceProvider
提供程序。
class PartnerMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$partner_id = $request->route('partner');
$partner = Partner::findOrFail($partner_id);
// set config
config([
'services.firebase.api_key' => $partner->firebase_api_key,
'services.firebase.auth_domain' => $partner->firebase_auth_domain,
'services.firebase.database_url' => $partner->firebase_database_url,
]);
app()->register(FirebaseClientServiceProvider::class);
return $next($request);
}
}