Laravel - Using (:any?) wildcard for ALL routes?

05/16/2020 09:00:02

I am having a bit of trouble with the routing.

I'm working on a CMS, and i need two primary routes. /admin and /(:any). The admin controller is used for the route /admin, and the view controller should be used for anything else than /admin. From the view controller, i will then parse the url and show the correct content.

This is what i have:

Route::get(array('admin', 'admin/dashboard'), array('as' => 'admin', 'uses' =>'[email protected]'));
Route::any('(:any)', '[email protected]');

The first route works, but the second one doesn't. I played around with it a little bit, and it seems if i use (:any) without the question mark, it only works if i put something after /. If i do put the question mark there, it doesn't work at all.

I want all of the following routes to go to [email protected]:

/
/something
/something/something
/something/something/something
/something/something/something/something
...etc...

Is this possible without hardcoding a bunch of (:any?)/(:any?)/(:any?)/(:any?) (which i don't even know works)?

What's the best way to go about this?

Verified Answer (28 Votes)

11/09/2012 01:49:54

Edit: There has been some confusion since the release of Laravel 4 regarding this topic, this answer was targeting Laravel 3.

There are a few ways to approach this.

The first method is matching (:any)/(:all?):

Route::any('(:any)/(:all?)', function($first, $rest=''){
    $page = $rest ? "{$first}/{$rest}" : $first;
    dd($page);
});

Not the best solution because it gets broken into multiple parameters, and for some reason (:all) doesn't work by itself (bug?)

The second solution is to use a regular expression, this is a better way then above in my opinion.

Route::any( '(.*)', function( $page ){
    dd($page);
});

There is one more method, which would let you check if there are cms pages even when the route may have matched other patterns, provided those routes returned a 404. This method modifies the event listener defined in routes.php:

Event::listen('404', function() {
    $page = URI::current();
    // custom logic, else
    return Response::error('404');
});

However, my preferred method is #2. I hope this helps. Whatever you do, make sure you define all your other routes above these catch all routes, any routes defined after will never trigger.

28

Answer #2 (95 Votes)

01/02/2016 15:50:39

Laravel 5

This solution works fine on Laravel 5:

Route::get('/admin', function () {

  // url /admin

});

Route::get('/{any}', function ($any) {

  // any other url, subfolders also

})->where('any', '.*');

Lumen 5

This is for Lumen instead:

$app->get('/admin', function () use ($app) {
  //
});

$app->get('/{any:.*}', function ($any) use ($app) {
  //
});
95

Answer #3 (47 Votes)

03/23/2013 16:29:36

Hitting a 404 status seems a bit wrong to me. This can get you in all kind of problems when logging the 404's. I recently bumped into the same wildcard routing problem in Laravel 4 and solved it with the following snippet:

Route::any('{slug}', function($slug)
{
    //do whatever you want with the slug
})->where('slug', '([A-z\d-\/_.]+)?');

This should solve your problem in a controlled way. The regular expression can be simplified to:

'(.*)?'

But you should use this at your own risk.

Edit (addition):

As this overwrites a lot of routes, you should consider wrapping it in an "App::before" statement:

    App::before(function($request) {
            //put your routes here
    });

This way, it will not overwrite custom routes you define later on.

47
3
Hack Hex uses Stack Exchance API by the Stack Exchange Inc. to scrape questions/answers under Creative Commons license.