2

我创建了一个名为 PathParser 的中间件类,它在每个请求上运行。目的是处理我们允许用户在我们的 Laravel 之前的原生 PHP 应用程序中创建的“虚 URL 路径”请求。例如:用户创建了一个 URL 路径,例如:http ://example.com/i-love-this-place

PathParser 所做的是检查 404 响应,然后查看 URL 路径是否与我们的旧虚路径之一匹配。像这样:

class PathParser
{   
    public function handle($request, Closure $next, $guard = null)
    {
        $next_response = $next($request);       
        $status_code = $next_response->getStatusCode();

        if ($status_code === 404) {
            $script_url = $request->server("SCRIPT_URL");

            $vanity_controller = new VanityController();
            $found_vanity_id = Search::findVanityPath($script_url);

            if (!empty($found_vanity_id)) {
                $next_response = response()->make($vanity_controller->one($found_vanity_id));
            }
        }

        return $next_response;
    }
}

假设如下:

  1. 用户从未创建过会与任何路由冲突的 URL 路径

  2. 必须支持一些现有的(Laravel 之前的)虚 URL 路径,这些路径在野外 - 发布到社交媒体等等。

在 Kernel.php 中,我有以下内容:

protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\PathParser::class,
        //\Illuminate\Session\Middleware\StartSession::class,
        //\Illuminate\View\Middleware\ShareErrorsFromSession::class,
    ];

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],    
    ];

在 $middleware 数组中,我尝试添加 StartSession 和 ShareErrorsFromSession (取消注释上面的 2 行),这部分工作。有两个主要问题:

  • Auth::user 为空,即使对于登录用户对虚路径的请求也是如此
  • 当用户提交不正确/无效信息时,$errors 不再在表单提交时填充(例如在注册和登录页面上)

有没有一种方法既可以检查所有请求的路由,又可以获取经过身份验证的用户,同时保留 $errors?

我有一种感觉,我对请求生命周期的理解不足以成功。但也许有办法?

如果无法满足我的要求,那么使用 302 重定向到标准化的前缀路径(例如http://example.com/vanity/i-love-this-place 是一个很好的解决方案。但我希望有另一种方法。

4

1 回答 1

1

几个建议:

如果您不需要 auth/sessions/etc,那么您可以Symfony\Component\HttpKernel\Exception\NotFoundHttpException在应用程序的异常处理程序中处理异常。

app/Exceptions/Handler.php中,将方法修改render()为如下所示:

public function render($request, Exception $e)
{
    if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
        // your code that returns a Response
    }

    return parent::render($request, Exception $e);
}

如果您确实需要 auth/sessions/etc,我建议您在路由文件的末尾创建一个“catchall”路由。例如,作为routes/web.php文件的最后一行,输入:

Route::any('{catchall}', 'VanityController@handle')->where('catchall', '(.*)');

然后,在你的内部VanityController,有一个handle看起来像这样的方法:

public function handle(Request $request, $url)
{
    // logic to search and render your vanity page for $url

    // if no vanity page was found:
    throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
}
于 2016-12-24T06:02:44.563 回答