Laravel 路由来检查多个字符串

Posted

技术标签:

【中文标题】Laravel 路由来检查多个字符串【英文标题】:Laravel route to check for multiple string 【发布时间】:2020-08-03 21:00:42 【问题描述】:

我想为某些包含以下内容的路由重定向 (301) -

page=1(查询字符串)或 index.php?&(查询字符串)

我已将路线添加为 -

Route::get('/any_url', 'UsersController@processRedirect')->where('any_url', '(.*)index\.php(.*)|(.*)page=1(.*)|(.*)|?&(.*)');

当我在https://regex101.com/ 中进行检查时,它正在工作,但在我的应用程序中却无法正常工作。

可能是什么问题?

我已通过 MiddleWare 完成此操作,但我不想检查所有 url。

还有其他方法可以实现吗?

【问题讨论】:

你是如何测试这个的?我可以想象只能检查index.php,其他任何东西都是路由未涵盖的url参数,你需要检查你的processRedirect方法 我无法检查是。它也不适用于index.php。有什么办法吗?我已经通过MiddleWare 完成了这项工作,但我不想检查所有网址。 为什么不在 .htaccess 和 rewrite 模块中这样做? @jgetner,我们希望避免对所有路线进行检查和处理。 你的意思是你还有其他路线吗? 【参考方案1】:

所以诀窍不是在路由中执行此操作,而是创建一个全局捕获所有路由来捕获所有路由,然后您可以在控制器中对路径或查询字符串进行任何处理。这使您的路线保持清洁和易于使用,并允许对查询字符串和路径或基本 url 的处理具有更大的权力。请务必删除您要使用此 catch all 路线处理的路线。

routes/web.php

//make this last route to catch
Route::any('/any', "ProcessRequestController@handler")->where("any", ".*");

App/Http/Controllers/ProcessController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;


class ProcessRequestController extends Controller

    public function handler(Request $request)
        //from here you can now access each section of the route a little more conviently.
        $request->path();
        if($request->has('page'))

        
    

【讨论】:

这可以解决问题。我会试试这个并检查。 一定要在路由文件最底部添加路由需要添加 @ChristopheHubert 是的。我忘记了路线顺序效果。谢谢。 我们将无法实现这种方式,因为路由将匹配以前的路由。 您需要将其添加到所有其他路由之后。这必须是最后一条路线,因为您是正确的,它将捕获所有路线,因此在您的路线顺序中放置是使其正常工作的关键。如果您可以提供路线,我们可以进一步帮助您正确进行此设置。【参考方案2】:

中间件可能是更好的解决方案。

包罗万象的路线有效,但会产生意想不到的后果。您将不得不手动处理 404 错误。您可能还会注意到性能下降,具体取决于您的路线设置方式。

与包罗万象的路由不同,中间件可以在任何路由匹配之前运行。中间件也可以附加到一组路由或特定路由。还有其他默认运行的中间件类,例如 Authentication 和 CORS。

这里是中间件的最新文档。自 Laravel 5 以来,中间件并没有太大变化,但最新的文档更好地解释了这个概念。 https://laravel.com/docs/7.x/middleware


以下是使用中间件解决问题的方法。

创建一个中间件类。

php artisan make:middleware My301Filter

如果您希望中间件在所有请求上运行,请在 app/http/kernel.php 中注册该类

protected $middleware = [
    // ...
    \App\Http\Middleware\My301Filter::class
];

然后您可以使用任何您想要的方式解析您的路线。使用逻辑来确定是否应调用 301 或应用程序是否应继续。 $next 闭包将转到下一个中​​间件或路由。

我选择在我的中间件课上写这样的东西。但是,此代码并不完美,您可能需要对其进行更改以满足您的需要。

<?php

namespace App\Http\Middleware;

use Closure;

class My301Filter


    // ...

    public function handle($request, Closure $next)
    
        $needles = ["page=1", "index.php", "?&"];

        foreach ($needles as $needle) 
            if (strpos($request->getRequestUri(), $needle) !== false) 
                return redirect('/some/route', 301);
            
        

        return $next($request);
    

【讨论】:

目前仅使用 MiddleWare,但避免使用 MiddleWare 无法检查所有路由 这不是解决此问题的好方法。问题变成你必须将此中间件应用于所有路由或特定路由。如果您将此应用于所有路线,则无论路线如何,它都会运行。只有在检查了所有其他路线后,才会运行全局捕获路线。如果您不使用全局中间件,则必须将其附加到各个路由,这似乎不太实用,提供了替代解决方案。 将中间件附加到特定路由是实用的。路由组可用于包含具有相同中间件的许多路由。如果组与请求不匹配,则中间件将不会运行。包罗万象的路线依赖于所有其他失败的路线。因此,如果查询字符串包含page=1,并且还匹配了另一个路由,那么包罗万象的路由将不会运行。路由组的中间件在 5.x 中可用 laravel.com/docs/5.0/routing#route-parameters

以上是关于Laravel 路由来检查多个字符串的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 如何在日期字符串中检查当前月份?

多个控制器的单个 Laravel 路由

Laravel 路由模型绑定 - Laravel 5.7

Laravel 中间件/路由组

如何检查路由“URL”是否存在?

Laravel 路由:使用 URL 查询字符串时如何路由?