搜索

首页  >  问答  >  正文

如何避免警告:在PhpStorm / Lumen中正确标记call_user_func时,确保在相应的'try'块中抛出异常?

<p>我的 Lumen 应用程序中有身份验证中间件,如下所示:</p> <pre class="brush:php;toolbar:false;">class Authenticate { public function handle(Request $request, Closure $next, string|null $guard = null): mixed { try { /**@var \Illuminate\Auth\RequestGuard $requestGuard*/ $requestGuard = $this->auth->guard($guard); $signedIn = $requestGuard->check(); // ... } catch (NoUserIdProvidedException) { // ... } // ... } }</pre> <p>它工作得很好,但 PhpStorm 报告说,异常(我从示例中删除了大部分,有一些)不是由包含块抛出的,尽管它们是这样。</p> <p>似乎在 RequestGuard 的深处它使用了 call_user_func</p> <pre class="brush:php;toolbar:false;">return $this->user = call_user_func( $this->callback, $this->request, $this->getProvider() );</pre> <p>调用 AuthServiceProvider 中设置的闭包,该闭包使用自定义 Security 类上的中间件方法:</p> <pre class="brush:php;toolbar:false;">class AuthServiceProvider extends ServiceProvider { public function boot(): void { $this->app['auth']->viaRequest('api', function ($request) { $security = new Security(); return $security->middleware($request); }); } }</pre> <p>在我看来,中间件的文档块正确无误</p> <pre class="brush:php;toolbar:false;">/*** @param 请求 $request * @return bool|对象|null * @抛出InvalidDomainUser * @抛出NoDomainUserException * @抛出NoTokenOnRecordException * @抛出NoTokenProvidedException * @抛出NoUserException * @抛出NoUserIdProvidedException*/ public function middleware(Request $request): object|bool|null {</pre> <p>添加文档块,例如:</p> <pre class="brush:php;toolbar:false;">/*** @抛出NoUserIdProvidedException*/</pre> <p>在闭包中,身份验证提供程序或处理代码不会使警告消失,是否有办法对代码进行注释或键入提示以避免误报?我不想直接关闭检查。</p>
P粉009186469P粉009186469464 天前503

全部回复(1)我来回复

  • P粉805535434

    P粉8055354342023-09-04 21:30:05

    对于静态分析来说,守卫的工作方式似乎有点过于复杂,因此我进行了重构,将底层自定义代码从守卫中移出,直接移入中间件,这样就成功了,现在可以正确检测到异常.

    class Authenticate
    {
        public function handle(Request $request, Closure $next, string|null $guard = null): mixed
        {
            try {
                $security = new Security();
                $user = $security->middleware($request);
                $signedIn = !empty($user->id);
    
                // ...
    
            } catch (NoUserIdProvidedException) {
                // ...
            }
    
            // ...
        }
    }

    安全类是自定义逻辑,重要的是带有@throws的文档块足够接近,可以被IDE找到

    class Security{
        /**
         * @param Request $request
         * @return bool|object|null
         * @throws InvalidDomainUser
         * @throws NoDomainUserException
         * @throws NoTokenOnRecordException
         * @throws NoTokenProvidedException
         * @throws NoUserException
         * @throws NoUserIdProvidedException
         */
        public function middleware(Request $request): object|bool|null
        {
          // ....
        }
    }

    回复
    0
  • 取消回复