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 路由来检查多个字符串的主要内容,如果未能解决你的问题,请参考以下文章