I want redirects (301) for some routes which contains the following -
page=1
(query string) or
index.php
or
?&
(query string)
I have added the route as -
Route::get('/{any_url}', 'UsersController@processRedirect')->where('any_url', '(.*)index\.php(.*)|(.*)page=1(.*)|(.*)|?&(.*)');
When I am checing in https://regex101.com/ it is working but in my app iit iis not working.
What could be the issue?
I have done this via MiddleWare but I do not want to check for all urls.
Is there any other way to achieve this?
So the trick is not to do this in the route but instead make a global catch all route that catches all routes and then you can do any handling of path or query string in your controller. This keeps your routes clean and easy to use and allows more power over processing of query strings and the path or base url. Be sure to remove the routes you want to handle with this catch all route.
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')){
}
}
}
Middleware is probably the better solution.
Catch-all routes work, but there are unintended consequences. You will have to manually handle 404 errors. You may also notice decreased performance depending on how your routes are setup.
Unlike catch-all routes, middleware can run before any routes are matched. Middleware can also be attached to a group of routes or a specific route. There are other middleware classes that are running by default, such as Authentication and CORS.
Here are the latest docs for middleware. Middleware hasn't changed much since Laravel 5, but the latest docs just explain the concept better. https://laravel.com/docs/7.x/middleware
Here is how you could use middleware to solve your problem.
Create a middleware class.
php artisan make:middleware My301Filter
If you want the middleware to run on all requests, register the class in app/http/kernel.php
protected $middleware = [
// ...
\App\Http\Middleware\My301Filter::class
];
Then you can parse your route using any way you want. Use logic to determine if a 301 should be called or if the app should continue. The $next
closure will go to the next middleware or route.
I chose to write something like this in my middleware class. However, this code is not perfect and you will probably have to change it to fit your needs.
<?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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With