【发布时间】:2018-06-22 17:13:37
【问题描述】:
在我的应用中,我有一组路线需要在调度之前进行一些引导。
为了说明情况:
有一个带有前缀“app”的特殊路由组。所有这些路线也都有一些参数:
site.dev/app/index?age=11&else=af3fs4ta21
如果没有这些参数,用户不应该被允许访问路由。我通过创建一个简单的路由中间件来完成它。
if (!$request->exists('age') || !$request->exists('else')) {
return redirect('/');
}
下一步是初始化一个将路由参数作为构造参数的类。然后参数“else”被用作数据库调用的参数。我需要从 /app 路由组访问每个路由中的此类。
为了实现我尝试设置服务提供者:
public function register()
{
$this->app->singleton(Dual::class, function ($app) {
return new Dual($this->app->request->all());
});
}
然后我创建了一个特殊的控制器扩展 BaseController 并将 Dual 类传递给它的构造函数。
class DualController extends Controller
{
public function __construct(Request $request, Dual $dual)
{
$this->middleware(\App\Http\Middleware\DualMiddleware::class);
$this->dual = $dual;
}
}
然后每个控制器都在扩展 DualController 并通过 $this->dual->method() 访问 Dual 类。
如果路由参数在他们的位置并且数据库中已经有一行,它就可以工作。
问题
这个中间件在 ServiceProvider 和 DualController 初始化类 Dual 之后执行。所以,中间件并没有真正起作用。如果路由参数不存在,它将失败。
此外,如果由于某种原因数据库中没有必需的行,则不会初始化 Dual 类(因为它取决于对 db 的调用)并且整个应用程序将崩溃,说我正在尝试对 null 执行操作。
期望的行为
首先检查路由是否存在参数。
其次,检查 db 中是否存在带有路由键的行。
第三 - 尝试初始化 Dual 类并将其传递给路由组 /app 使用的所有控制器。
如果任何步骤失败 -> 显示正确的消息。
部分双班:
class Dual
{
protected $client = null;
public $config = [];
public function __construct($config)
{
$this->config = $config;
$this->bootstrap();
}
public function getEli()
{
$eli = Eli::where(['else' => $this->config['else']])->first();
return $eli;
}
public function instantiateClient()
{
$client = Client::factory(Client::ADAPTER_OAUTH, [
'entrypoint' => $this->getEli()->eli_url,
'client_id' => '111',
'client_secret' => '111',
]);
$client->setAccessToken($this->getEli()->accessToken()->first()->access_token);
return $client;
}
public function getClient()
{
if ($this->client === null)
{
throw new \Exception('Client is NOT instantiated');
}
return $this->client;
}
public function bootstrap()
{
$this->client = $this->instantiateClient();
}
【问题讨论】:
-
为什么不能检查用户是否被允许进入中间件?
-
@AlexeyMezenin 如果您所说的用户是指已注册和登录的用户 - 这个应用程序中没有这样的东西,也不会。我试图检查 params 以及中间件中的 DB 中是否存在这样的模型,但只要 laravel 在控制器中构造和初始化类 Dual 后执行路由中间件,它就不会工作。
-
尝试将其作为路由中间件在
app/Http/Kernel.php中添加一个键,然后在您的路由文件->middleware('something')中定义它 -
@ahmad 感谢您的回复。起初我尝试过,仍然 - 中间件在服务提供者之后执行。另一方面,全局中间件工作正常(第一个中间件然后构造),但是全局是全局的,阻止了应用程序中的所有其他路由。
-
@AlexeyMezenin 我已经更新了导致问题的双重类的部分问题。问题主要出在 getEli()->accessToken() 部分,因为它尝试在 null 上执行它。
标签: php laravel laravel-middleware service-provider