Laravel - 为所有路由使用(:任何?)通配符?

qwe*_*rty 51 php routing wildcard laravel laravel-3

我在路由方面遇到了一些麻烦.

我正在使用CMS,我需要两条主要路线./admin/(:any).该admin控制器用于路由/adminview控制应该用于任何东西比其他/admin.从view控制器,那么我就要解析URL并显示正确的内容.

这就是我所拥有的:

Route::get(array('admin', 'admin/dashboard'), array('as' => 'admin', 'uses' =>'admin.dashboard@index'));
Route::any('(:any)', 'view@index');
Run Code Online (Sandbox Code Playgroud)

第一条路线有效,但第二条路线没有.我玩了一下它,似乎如果我使用(:any)没有问号,它只有在我放了一些东西后才有用/.如果我这样做把问号在那里,它不会在所有的工作.

我想要以下所有路由去查看@index:

/
/something
/something/something
/something/something/something
/something/something/something/something
...etc...
Run Code Online (Sandbox Code Playgroud)

这可能没有硬编码一堆(:any?)/(:any?)/(:any?)/(:any?)(我甚至不知道工作)?

最好的方法是什么?

And*_*rea 88

Laravel 5

这个解决方案在Laravel 5上运行良好:

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

  // url /admin

});

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

  // any other url, subfolders also

})->where('any', '.*');
Run Code Online (Sandbox Code Playgroud)

流明5

这是针对Lumen的:

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

$app->get('/{any:.*}', function ($any) use ($app) {
  //
});
Run Code Online (Sandbox Code Playgroud)


Eel*_*Bos 47

达到404状态对我来说似乎有点不对劲.这可以在记录404时遇到各种问题.我最近在Laravel 4中碰到了相同的通配符路由问题,并使用以下代码解决了它:

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

这应该以受控的方式解决您的问题.正则表达式可以简化为:

'(.*)?'
Run Code Online (Sandbox Code Playgroud)

但你应该自担风险使用它.

编辑(添加):

由于这会覆盖很多路由,因此您应该考虑将其包装在"App :: before"语句中:

    App::before(function($request) {
            //put your routes here
    });
Run Code Online (Sandbox Code Playgroud)

这样,它不会覆盖您稍后定义的自定义路由.

  • 是的,这是我使用的方法,它适用于L4.1,但我更喜欢这样的一行:`Route :: any('admin/{allsegments}',array('as'=>'admin', 'uses'=>'AppBackend\Controllers\AdminController @ index')) - > where('allsegments','(.*)?');` (3认同)

Wil*_*ley 27

编辑:自从Laravel 4发布关于这个主题以来,有一些混乱,这个答案针对的是Laravel 3.

有几种方法可以解决这个问题.

第一种方法是匹配(:any)/(:all?):

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

不是最好的解决方案,因为它被分解成多个参数,并且由于某种原因(:all)本身不起作用(bug?)

第二种解决方案是使用正则表达式,这是我认为的更好的方法.

Route::any( '(.*)', function( $page ){
    dd($page);
});
Run Code Online (Sandbox Code Playgroud)

还有一种方法,即使路由可能匹配其他模式,也可以检查是否有cms页面,前提是这些路由返回404.此方法修改了以下定义的事件监听器routes.php:

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

但是,我首选的方法是#2.我希望这有帮助.无论您做什么,请确保定义所有其他路线以上捕获所有路线,之后定义的任何路线将永远不会触发.

  • 如果您发现#2不起作用,您可能正在使用Laravel 4.在这种情况下,[此答案](http://stackoverflow.com/questions/16178426/get-all-routes-laravel-4)可能有所帮助.归结为`Route :: any('{all}',function($ page){dd($ page);}) - > where('all','.*');` (6认同)

Guy*_*Guy 7

Route::get("{path}", "SomeController@serve")->where('path', '.+');
Run Code Online (Sandbox Code Playgroud)

上面的代码将捕获您提到的递归子URL:

/
/something
/something/something
/something/something/something
/something/something/something/something
Run Code Online (Sandbox Code Playgroud)

任何其他特殊情况,例如admin/*,您可以在此之前捕获.


Ale*_*orb 7

Laravel 8 / 仅在子目录下重定向

我不想重定向所有不存在的 URL,而只想重定向特定子目录中的 URL(例如https://example.com/subdir/*

如果我只是想重定向所有丢失的 URL,我可以只使用web.php 文件末尾的后备路由:

Route::fallback(function () {
    //
});
Run Code Online (Sandbox Code Playgroud)

但由于我只想重定向子目录中的 url,所以我使用了这段代码,它对我有用(只是重定向到 /):

Route::get('subdirectory/{any}', function($page){return redirect()->to('/');})->where('any', '.*');
Run Code Online (Sandbox Code Playgroud)

我在FallbackRouteTest.php中找到了这个。


Luk*_*uke 6

只是拼写出我的经验,以防它帮助某人拼凑一些东西。

我在 Laravel 上构建了一个自消费 API 的 React 应用程序。它有一个由 Laravel/Lumen 服务的单一视图。它使用 React 路由器。 单击应用程序中的链接始终有效,但输入 URL 需要考虑以下因素:

在 Laravel 中,我在 web.php 路由文件中使用了以下内容:

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

一切都奏效了。

然后我将项目切换到 Lumen。感谢这篇文章,我在 web.php 路由文件中使用了以下内容:

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

这适用于第一级 URL,例如:

/
/something 
Run Code Online (Sandbox Code Playgroud)

然而,

/something/something etc.
Run Code Online (Sandbox Code Playgroud)

没有。

我查看了 Google Developer tools 中的 network 选项卡,注意到 app.js 的 URL 在 app.js前面附加了/something在二级和更高层 URLS 上,例如:

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)
Run Code Online (Sandbox Code Playgroud)

我所要做的就是在我的单一视图页面中为我的 app.js 源添加一个前导斜杠,例如:

<script src="/js/app.js" defer></script>
Run Code Online (Sandbox Code Playgroud)

代替:

<script src="js/app.js" defer></script>
Run Code Online (Sandbox Code Playgroud)

所以:

这在Laravel有效(这是一个 Blade 文件,可能会自动解析 js/app.js URL)

<script src="{{ asset('js/app.js') }}" defer></script>
Run Code Online (Sandbox Code Playgroud)

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

但是,我必须在Lumen (不是 Blade 文件)中执行此操作

<script src="/js/app.js" defer></script>
Run Code Online (Sandbox Code Playgroud)

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


Edm*_*mhs 5

在路径文件的末尾添加它

App::missing(function($exception)
{
    return View::make('notfound');
});
Run Code Online (Sandbox Code Playgroud)

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