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

前端 未结 8 1148
时光取名叫无心
时光取名叫无心 2020-11-29 03:18

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

相关标签:
8条回答
  • 2020-11-29 03:39

    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.

    0 讨论(0)
  • 2020-11-29 03:39
    Route::get("{path}", "SomeController@serve")->where('path', '.+');
    

    The above code will capture the recursive sub urls you mentioned:

    /
    /something
    /something/something
    /something/something/something
    /something/something/something/something
    

    Any other special cases, such as admin/*, you can capture before this one.

    0 讨论(0)
  • 2020-11-29 03:48

    Add this in the end of routes file

    App::missing(function($exception)
    {
        return View::make('notfound');
    });
    

    from http://scotch.io/tutorials/simple-and-easy-laravel-routing

    0 讨论(0)
  • 2020-11-29 03:51

    Just spelling-out my experience in case it helps someone piece something together.

    I built a self-API-consuming React app on Laravel. It has a single view served by Laravel/Lumen. It uses the React router. Clicking links in the app always worked, but typing-in URLs needed the following consideration:

    In Laravel I used the following in my web.php routes file:

    Route::view('/{path?}', 'app')
        ->where('path', '.*')
        ->name('react');
    

    And everything worked.

    Then I switched the project to Lumen. Thanks to this post, I used the following in my web.php routes file:

    $router->get('/{all:.*}', function() {
        return view('app');
    });
    

    This worked for first level URLS such as:

    /
    /something 
    

    However,

    /something/something etc.
    

    did not.

    I looked in the network tab in Google Developer tools and noticed that the URL for app.js was appending /something in front of app.js on second and higher tier URLS, such as:

    myapp.com/something
    app.js URL:  myapp.com/js/app.js  (as it should be)
    
    myapp.com/something/something
    app.js URL:  myapp.com/something/js/app.js  (not found)
    

    All I had to do was add a leading slash to my app.js source in my single view page such as:

    <script src="/js/app.js" defer></script>
    

    Instead of:

    <script src="js/app.js" defer></script>
    

    so:

    This worked in Laravel (It was a Blade file that may have automatically resolved the js/app.js URL)

    <script src="{{ asset('js/app.js') }}" defer></script>
    

    with

    Route::view('/{path?}', 'app')
        ->where('path', '.*')
        ->name('react');
    

    But, I had to do this in Lumen (Not a Blade file):

    <script src="/js/app.js" defer></script>
    

    with

    $router->get('/{all:.*}', function() {
        return view('app');
    });
    
    0 讨论(0)
  • 2020-11-29 03:55

    Having basic lumen scaffolding. In my case, I have 2 frontend apps and api routes

    <?php // routes/web.php
    /** @var \Laravel\Lumen\Routing\Router $router */
    
    $router->group([
        'prefix' => '/api/v1',
        'namespace' => 'App\Http\Controllers'
    ], function () use ($router) {
    
        require 'routes-group1.php';
        require 'routes-group2.php';
        // ...
    });
    
    $router->get('/admin{any:.*}', function () {
        return file_get_contents('../public/a/index.html');
    });
    
    $router->get('{any:.*}', function () {
        return file_get_contents('../public/m/index.html');
    });
    
    0 讨论(0)
  • 2020-11-29 03:58

    Thanks for the solution William. However methods 1 & 2 aren't working anymore Laravel 4, and in order to use solution #3 in Laravel 4 you will have to fire the 404 event in your start/global.php file.

    App::error(function(Exception $exception, $code)
    {
        // i.o. -> this is our catchall!
        // http://stackoverflow.com/questions/13297278/laravel-using-any-wildcard-for-all-routes
        Event::fire('404');
    
        return View::make('error')->with('exception', $exception)->with('code', $code);
    
        Log::error($exception);
    });
    

    Now we can handle this in our routes.php file:

    Event::listen('404', function() {
        // url?
        $url = Request::path();
    
        // LOGIC HERE
    
        // else
        return View::make('error');
    });
    
    0 讨论(0)
提交回复
热议问题