Laravel – 对所有路由使用(:any?)通配符?
我在路由方面有点麻烦。
我正在开发CMS,我需要两条主要路线。 /admin
和/(:any)
。 admin
控制器用于路由/admin
, view
控制器应该用于除/admin
以外的其他任何内容。 从view
控制器,我将然后parsingURL并显示正确的内容。
这是我有:
Route::get(array('admin', 'admin/dashboard'), array('as' => 'admin', 'uses' =>'admin.dashboard@index')); Route::any('(:any)', 'view@index');
第一条路线起作用,但第二条路线不起作用。 我玩了一下,似乎如果我使用(:any)
没有问号,它只有当我把东西后/
。 如果我把问号放在那里,那根本不起作用。
我想要所有以下路线去查看@ index:
/ /something /something/something /something/something/something /something/something/something/something ...etc...
这可能没有硬编码一堆(:any?)/(:any?)/(:any?)/(:any?)
(我甚至不知道作品)?
最好的办法是什么呢?
编辑:自从Laravel 4发布以来,这个主题出现了一些混乱,这个答案是针对Laravel 3的。
有几种方法可以解决这个问题。
第一种方法是匹配(:any)/(:all?)
:
Route::any('(:any)/(:all?)', function($first, $rest=''){ $page = $rest ? "{$first}/{$rest}" : $first; dd($page); });
不是最好的解决scheme,因为它被分解成多个参数,出于某种原因(:all)本身不起作用(bug?)
第二种解决scheme是使用正则expression式,这在我看来是更好的方法。
Route::any( '(.*)', function( $page ){ dd($page); });
还有一个方法可以让你检查是否有cms页面,即使路由可能与其他模式匹配,只要这些路由返回了404。这个方法修改routes.php
定义的事件监听器:
Event::listen('404', function() { $page = URI::current(); // custom logic, else return Response::error('404'); });
不过,我最喜欢的方法是#2。 我希望这有帮助。 无论你做什么,确保你定义所有其他路线上面这些捕获所有路线,任何定义后的路线将永远不会触发。
打404状态似乎有点不对我。 这可以让你在logging404的时候遇到各种各样的问题。 我最近在Laravel 4中遇到了同样的通配符路由问题,并用下面的代码解决了这个问题:
Route::any('{slug}', function($slug) { //do whatever you want with the slug })->where('slug', '([Az\d-\/_.]+)?');
这应该以可控的方式解决您的问题。 正则expression式可以简化为:
'(.*)?'
但是你应该自己承担风险。
编辑(添加):
由于这会覆盖很多路由,因此应该考虑将其封装在“App :: before”语句中:
App::before(function($request) { //put your routes here });
这样,它将不会覆盖您以后定义的自定义路由。
Laravel 5
此解决scheme在Laravel 5上正常工作:
Route::get('/admin', function () { // url /admin }); Route::get('/{any}', function ($any) { // any other url, subfolders also })->where('any', '.*');
stream明5
这是为了stream明,而不是:
$app->get('/admin', function () use ($app) { // }); $app->get('/{any:.*}', function ($any) use ($app) { // });
将这添加到路由文件的末尾
App::missing(function($exception) { return View::make('notfound'); });
感谢解决scheme威廉。 然而,方法1和2不再工作Laravel 4,并且为了使用Laravel 4中的解决scheme#3,您将必须在start / global.php文件中触发404事件。
App::error(function(Exception $exception, $code) { // io -> 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); });
现在我们可以在我们的routes.php文件中处理这个:
Event::listen('404', function() { // url? $url = Request::path(); // LOGIC HERE // else return View::make('error'); });
Route::get("{path}", "SomeController@serve")->where('path', '.+');
上面的代码将捕获你提到的recursion子url:
/ /something /something/something /something/something/something /something/something/something/something
任何其他特殊情况下,如admin / *,您可以在此之前捕获。