如何使 Laravel 中的路由不区分大小写?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31964973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:09:50  来源:igfitidea点击:

How to make routes in Laravel case insensitive?

phpregexlaravellaravel-5laravel-routing

提问by Nishant Srivastava

I have a project in laravel and there are many routes in that project.

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

But i just discovered that the routes are all case sensitive, means /advertiser/reportsis different than /advertiser/Reports.

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

So what i want is both the routes should redirect to same view. Currently /advertiser/Reportsgives RouteNotFound Exception.

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

I have read about the Route::pattern()way of doing it but since there are many routes i'll have to put in a lot of efforts for that. So, what i want is a better way of doing it, if there is any.

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

回答by jedrzej.kurylo

In order to make routes case-insensitive you'll need to modify the way routes are matched with the URLs. In Laravel, it all happens in UriValidatorobject so you'll need to create your own validator.

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

Luckily, like most tasks in Laravel, it's not really complicated.

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

First, create the new validator class - the only difference between this one and the original is that you'll append the imodifier at the end of regular expression for the compiled route to switch enable case-insensitive matching.

首先,创建新的验证器类 - 这个和原始类之间的唯一区别是,您将在编译路由的正则表达式末尾附加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));
  }
}

Secondly, you need to update the list of matchers that are used to match URL to a route and replace the original UriValidatorwith yours.

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

In order to do that, add the following at the top of your routes.phpfile:

为此,请在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;
});

This will remove the original validator and add yours to the list of validators.

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

Keep in mind that this code has not been tested by running. Let me know if there are any typos or something doesn't work as expected. I'll be more than happy to get that working for you :)

请记住,此代码尚未经过运行测试。让我知道是否有任何拼写错误或无法按预期工作。我会很高兴为你工作:)

回答by rmondesilva

I know this is an old question but I came across this same problem and I just want to share my solution.

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

On method render(...)at Exceptions/Handler.php, catch 404 exceptions and validate the case of the URL then redirect like this:

render(...)在 Exceptions/Handler.php 的方法上,捕获 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);
}

That's it.

就是这样。

回答by S..

I wrote a gist which does this: https://gist.github.com/samthomson/f670f9735d200773e543

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

Edit your app/filters.php to check for uppercase characters in the route and redirect them to a converted route.

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