我在路由方面遇到了一些麻烦。
我正在使用CMS,我需要两条主要路线。 /admin
和/(:any)
。 admin
控制器用于路线/admin
,而view
控制器应该用于除/admin
之外的任何其他东西。从view
控制器,我将解析网址并显示正确的内容。
这就是我所拥有的:
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);
});
不是最好的解决方案,因为它被分解成多个参数,并且由于某种原因(:all)本身不起作用(bug?)
第二种解决方案是使用正则表达式,这是我认为的更好的方法。
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。我希望这有帮助。无论您做什么,请确保定义所有其他路线以上捕获所有路线,之后定义的任何路线将永远不会触发。
这个解决方案在Laravel 5上运行良好:
Route::get('/admin', function () {
// url /admin
});
Route::get('/{any}', function ($any) {
// any other url, subfolders also
})->where('any', '.*');
这是针对Lumen的:
$app->get('/admin', function () use ($app) {
//
});
$app->get('/{any:.*}', function ($any) use ($app) {
//
});
达到404状态对我来说似乎有点不对劲。这可以在记录404时遇到各种问题。我最近在Laravel 4中碰到了相同的通配符路由问题,并使用以下代码解决了它:
Route::any('{slug}', function($slug)
{
//do whatever you want with the slug
})->where('slug', '([A-z\d-\/_.]+)?');
这应该以受控的方式解决您的问题。正则表达式可以简化为:
'(.*)?'
但你应该自担风险使用它。
编辑(添加):
由于这会覆盖很多路由,因此您应该考虑将其包装在“App :: before”语句中:
App::before(function($request) {
//put your routes here
});
这样,它不会覆盖您稍后定义的自定义路由。
Route::get("{path}", "SomeController@serve")->where('path', '.+');
上面的代码将捕获您提到的递归子URL:
/
/something
/something/something
/something/something/something
/something/something/something/something
任何其他特殊情况,例如admin / *,您可以在此之前捕获。
在路径文件的末尾添加它
App::missing(function($exception)
{
return View::make('notfound');
});
来自http://scotch.io/tutorials/simple-and-easy-laravel-routing
谢谢你的解决方案威廉。但是,方法1和2不再适用于Laravel 4,并且为了在Laravel 4中使用解决方案#3,您必须在start / global.php文件中触发404事件。
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);
});
现在我们可以在routes.php文件中处理这个:
Event::listen('404', function() {
// url?
$url = Request::path();
// LOGIC HERE
// else
return View::make('error');
});
有基本的管腔脚手架。就我而言,我有2个前端应用程序和api路由
<?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');
});
只是拼出我的经验,以防有人把某事拼凑在一起。
我在Laravel上构建了一个自我API消耗的React应用程序。 Laravel / Lumen餐厅享有独特的景致。它使用React路由器。单击应用程序中的链接始终有效,但输入URL需要以下考虑因素:
在Laravel中,我在web.php路由文件中使用了以下内容:
Route::view('/{path?}', 'app')
->where('path', '.*')
->name('react');
一切顺利。
然后我把项目改为Lumen。感谢这篇文章,我在web.php路由文件中使用了以下内容:
$router->get('/{all:.*}', function() {
return view('app');
});
这适用于第一级URL,例如:
/
/something
然而,
/something/something etc.
没有。
我查看了Google Developer工具中的网络标签,发现app.js的网址是在第二层和更高层网址上的app.js前面附加/某些内容,例如:
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)
我所要做的就是在单个视图页面中为我的app.js源添加一个前导斜杠,例如:
<script src="/js/app.js" defer></script>
代替:
<script src="js/app.js" defer></script>
所以:
这在Laravel中工作(这是一个可能自动解析js / app.js URL的Blade文件)
<script src="{{ asset('js/app.js') }}" defer></script>
同
Route::view('/{path?}', 'app')
->where('path', '.*')
->name('react');
但是,我必须在Lumen(非刀片文件)中执行此操作:
<script src="/js/app.js" defer></script>
同
$router->get('/{all:.*}', function() {
return view('app');
});