【问题标题】:How to make routes in Laravel case insensitive?如何使 Laravel 中的路线不区分大小写?
【发布时间】:2015-11-05 01:09:30
【问题描述】:

我在 laravel 有一个项目,该项目中有很多路线。

但我刚刚发现路由都是区分大小写的,意味着 /advertiser/reports/advertiser/Reports 不同。

所以我想要的是两条路线都应该重定向到同一个视图。现在 /advertiser/Reports 给出 RouteNotFound 异常。

我已经阅读了关于 Route::pattern() 的方法,但是由于有很多路线,我必须为此付出很多努力。所以,我想要的是一种更好的方法,如果有的话。

【问题讨论】:

  • 也许这会有所帮助:stackoverflow.com/a/21752884/1409771
  • 我已经看过了..我也在问题中写了这个..但为此我将不得不更改我的每条路线,这就像为我再次编写整个 routes.php 一样我正在寻找一个更好的选择。
  • 您应该问自己的最重要的问题:为什么?你为什么要这么做?
  • 先生,因为我希望我的应用程序中的 url 不区分大小写,因为据我所知,url 不区分大小写
  • 好吧,让我们再试一次 - 为什么你的应用应该支持不区分大小写的路由?所以你可以输入任何东西或什么?我不认为你需要支持。如果不需要,那你就没有问题。

标签: php regex laravel laravel-5 laravel-routing


【解决方案1】:

为了使路由不区分大小写,您需要修改路由与 URL 匹配的方式。在 Laravel 中,这一切都发生在 UriValidator 对象中,因此您需要创建自己的验证器。

幸运的是,像 Laravel 中的大多数任务一样,它并不复杂。

首先,创建新的验证器类 - 这个和原来的唯一区别是你将在正则表达式的末尾附加 i 修饰符,以便编译路由切换启用情况-不敏感的匹配。

<?php namespace Your\Namespace;

use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Routing\Matching\ValidatorInterface;

class CaseInsensitiveUriValidator implements ValidatorInterface
{
  public function matches(Route $route, Request $request)
  {
    $path = $request->path() == '/' ? '/' : '/'.$request->path();
    return preg_match(preg_replace('/$/','i', $route->getCompiled()->getRegex()), rawurldecode($path));
  }
}

其次,您需要更新用于将 URL 匹配到路由的匹配器列表,并将原始 UriValidator 替换为您的。

为此,请在 routes.php 文件的顶部添加以下内容:

<?php
use Illuminate\Routing\Route as IlluminateRoute;
use Your\Namespace\CaseInsensitiveUriValidator;
use Illuminate\Routing\Matching\UriValidator;

$validators = IlluminateRoute::getValidators();
$validators[] = new CaseInsensitiveUriValidator;
IlluminateRoute::$validators = array_filter($validators, function($validator) { 
  return get_class($validator) != UriValidator::class;
});

这将删除原始验证器并将您的验证器添加到验证器列表中。

请记住,此代码未经运行测试。让我知道是否有任何拼写错误或某些东西没有按预期工作。我很乐意为您服务:)

【讨论】:

  • 首先感谢您的回复。现在我使用您的代码引发了以下异常:Missing argument 2 for array_except()
  • 先生,它仍然无法正常工作,我不知道该怎么办。它给出了这个异常: [Symfony\Component\Debug\Exception\FatalErrorException] 类 Illuminate\Routing\Matching\MethodValidator 的对象无法转换为字符串
  • 很好,我们到了。我更新了答案 - 您需要添加到 routes.php 的代码
  • 你在 routes.php 文件顶部的代码至少应该放在你的 AppServiceProvider 中。
【解决方案2】:

我写了一个要点:https://gist.github.com/samthomson/f670f9735d200773e543

编辑您的 app/filters.php 以检查路由中的大写字符并将它们重定向到转换后的路由。

【讨论】:

    【解决方案3】:

    我知道这是一个老问题,但我遇到了同样的问题,我只想分享我的解决方案。

    在 Exceptions/Handler.php 的方法 render(...) 上,捕获 404 异常并验证 URL 的大小写,然后像这样重定向:

    public function render($request, Exception $exception)
    {
        $url = $request->url();
        $loweredCaseUrl = strtolower($url);
        if (
            $exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException &&
            $url !== $loweredCaseUrl
        ) {
            return redirect($loweredCaseUrl);
        }
    
        return parent::render($request, $exception);
    }
    

    就是这样。

    【讨论】:

    • 小错字,在loweredCaseUrl前面去掉“$”
    猜你喜欢
    • 2014-03-10
    • 2020-01-26
    • 2016-11-24
    • 1970-01-01
    • 2014-02-15
    • 2011-10-14
    • 2015-07-05
    • 1970-01-01
    • 2021-04-29
    相关资源
    最近更新 更多