php Laravel 5 应用中的动态路由
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33003097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic Routing in Laravel 5 Application
提问by Becky
I am hoping that someone can help me out with dynamic routing for urls that can have multiple segments. I've been doing some searching all over the web, but nothing I find helps me out with my specific situation.
我希望有人可以帮助我解决可以有多个段的 url 的动态路由。我一直在网上进行一些搜索,但我发现没有任何东西可以帮助我解决我的具体情况。
A little background ... several years ago, I developed a CMS package for custom client websites that was built on CodeIgniter. This CMS package has several modules (Pages, Blog, Calendar, Inquiries, etc). For the Pages module, I was caching the routes to a "custom routes" config file that associated the full route for the page (including parent, grandparent, etc) with the ID of the page. I did this so that I didn't have to do a database lookup to find the page to display.
一点背景……几年前,我为基于 CodeIgniter 构建的自定义客户端网站开发了一个 CMS 包。这个 CMS 包有几个模块(页面、博客、日历、查询等)。对于 Pages 模块,我将路由缓存到“自定义路由”配置文件中,该文件将页面(包括父级、祖父级等)的完整路由与页面 ID 相关联。我这样做是为了不必进行数据库查找来查找要显示的页面。
I am currently working on rebuilding this CMS package using Laravel (5.1) [while I'm learning Laravel]. I need to figure out the routing situation before I can move on with my Pages module in the new version of the package.
我目前正在使用 Laravel (5.1) [在学习 Laravel 的同时] 重建这个 CMS 包。我需要弄清楚路由情况,然后才能继续使用新版本包中的 Pages 模块。
I know that I can do something like ...
我知道我可以做一些像......
// routes.php
Route::get('{slug}', ['uses' => 'PageController@view']);
// PageController.php
class PageController extends Controller
{
public function view($slug)
{
// do a query to get the page by the slug
// display the view
}
}
And this would work if I didn't allow nested pages, but I do. And I only enforce uniqueness of the slug based on the parent. So there could be more than one page with a slug of fargo...
如果我不允许嵌套页面,这会起作用,但我这样做了。我只根据父级强制执行 slug 的唯一性。因此,可能会有不止一页带有Fargoslug 的页面......
- locations/fargo
- staff/fargo
- 地点/法戈
- 工作人员/法戈
As with the package that I built using CodeIgniter, I would like to be able to avoid extra database lookups to find the correct page to display.
与我使用 CodeIgniter 构建的包一样,我希望能够避免额外的数据库查找来找到要显示的正确页面。
My initial thought was to create a config file that would have the dynamic routes like I did with the old version of the system. The routes will only change at specific times (when page is created, when slug is modified, when parent is changed), so "caching" them would work great. But I'm still new to Laravel, so I'm not sure what the best way to go about this would be.
我最初的想法是创建一个具有动态路由的配置文件,就像我在旧版本系统中所做的那样。路由只会在特定时间更改(创建页面时,修改 slug 时,更改父项时),因此“缓存”它们会很好用。但我还是 Laravel 的新手,所以我不确定最好的方法是什么。
I did manage to figure out that the following routes work. But is this the best way to set this up?
我确实设法弄清楚以下路线有效。但这是设置它的最佳方式吗?
Route::get('about/foobar', function(){
return App::make('\App\Http\Controllers\PageController')->callAction('view', [123]);
});
Route::get('foobar', function(){
return App::make('\App\Http\Controllers\PageController')->callAction('view', [345]);
});
Basically, I would like to bind a specific route to a specific page ID when the page is created (or when the slug or parent are changed).
基本上,我想在创建页面时(或更改 slug 或父级时)将特定路由绑定到特定页面 ID。
Am I just overcomplicating things?
我只是把事情复杂化了吗?
Any help or direction regarding this would be greatly appreciated.
任何有关这方面的帮助或指导将不胜感激。
Thanks!
谢谢!
回答by Jeemusu
The way I handle this is to use two routes, one for the home page (which generally contains more complex logic like news, pick up articles, banners, etc), and a catch all for any other page.
我处理这个问题的方法是使用两种路由,一种用于主页(通常包含更复杂的逻辑,如新闻、文章、横幅等),另一种用于任何其他页面。
Routes
路线
// Home page
Route::get('/', [
'as' => 'home',
'uses' => 'PageController@index'
]);
// Catch all page controller (place at the very bottom)
Route::get('{slug}', [
'uses' => 'PageController@getPage'
])->where('slug', '([A-Za-z0-9\-\/]+)');
The important part to note in the above is the ->where()
method chained on the end of the route. This allows you to declare regex pattern matching for the route parameters. In this case I am allowing alphanumeric characters, hyphens and forward slashes for the {slug}
parameter.
上面要注意的重要部分是->where()
链接在路由末尾的方法。这允许您为路由参数声明正则表达式模式匹配。在这种情况下,我允许参数使用字母数字字符、连字符和正斜杠{slug}
。
This will match slugs liketest-page
test-page/sub-page
another-page/sub-page
这将匹配像test-page
test-page/sub-page
another-page/sub-page
PageController Methods
页面控制器方法
public function index()
{
$page = Page::where('route', '/')->where('active', 1)->first();
return view($page->template)
->with('page', $page);
}
public function getPage($slug = null)
{
$page = Page::where('route', $slug)->where('active', 1);
$page = $page->firstOrFail();
return view($page->template)->with('page', $page);
}
I keep the template file information in the database, as I allow users to create templates in the content management system.
我将模板文件信息保存在数据库中,因为我允许用户在内容管理系统中创建模板。
The response from the query on the database is then passed to the view where it can be output to the metadata, page, breadcrumbs, etc.
来自数据库查询的响应然后被传递到视图,在那里它可以输出到元数据、页面、面包屑等。
回答by Asif Khan
I was also looking for the same answer that is about creating a dynamic routing in laravel i come up with this: In routes.php
我也在寻找与在 laravel 中创建动态路由相同的答案,我想出了这个:在 routes.php
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
$str=Request::url();
$del="/public/";
$pos=strpos($str, $del);
$important1=substr($str, $pos+strlen($del), strlen($str)-1);
$important=ucfirst($important1);
$asif=explode("/", $important);
$asif1=explode("/", $important1);
//echo $important;
$post=$asif1[0];
$post1=$asif1[1];
if(isset($asif1[2]))
{
$post2=$asif1[2];
}
if(!(isset($post2)))
{
Route::match(array('GET','POST'),$important1, $asif[0].'Controller@'.$asif[1]);
}
if(isset($post2))
{ Route::match(array('GET','POST'),$post.'/'.$post1.'/{id}',$asif[0].'Controller@'.$asif[1]);
}
Route::get('/', function () {
return view('welcome');
});
Ex
前任
if you have PostController with method hello in laravel. You can use this url http://localhost/shortproject/public/post/hello. Where shortproject is your project folder name.
如果你在 Laravel 中有带有 hello 方法的 PostController。您可以使用此网址http://localhost/shortproject/public/post/hello。其中 shortproject 是您的项目文件夹名称。