我有下表:mysql数据库中的group_pages,页面名称为route name:
id name route
--------------------
0 About about
1 Contact contact
2 Blog blog
我要做的是在my:routes.php中创建动态路由?
如果我转到例如:/about
它将转到AboutController.php
(将动态创建)可能吗?是否可以创建动态控制器文件?
我正在尝试创建链接到控制器的动态页面路由
示例我想在我的routes.php
Route::controller('about', 'AboutController');
Route::controller('contact', 'ContactController');
Route::controller('blog', 'BlogController');
答案 0 :(得分:30)
这不是创建动态页面的正确方法,您应该使用数据库并将所有页面保留在数据库中。例如:
// Create pages table for dynamic pages
id | slug | title | page_content
然后创建Page
Eloquent
模型:
class Page extends Eloquent {
// ...
}
然后为Controller
创建CRUD
,您可以使用resource
控制器或普通控制器,例如,通常为PageController
:
class PageController extends BaseController {
// Add methods to add, edit, delete and show pages
// create method to create new pages
// submit the form to this method
public function create()
{
$inputs = Input::all();
$page = Page::create(array(...));
}
// Show a page by slug
public function show($slug = 'home')
{
$page = page::whereSlug($slug)->first();
return View::make('pages.index')->with('page', $page);
}
}
views/page/index.blade.php
视图文件:
@extends('layouts.master')
{{-- Add other parts, i.e. menu --}}
@section('content')
{{ $page->page_content }}
@stop
要显示页面,请创建如下路线:
// could be page/{slug} or only slug
Route::get('/{slug}', array('as' => 'page.show', 'uses' => 'PageController@show'));
要访问某个页面,您可能需要url/link
,如下所示:
http://example.com/home
http://example.com/about
这是一个粗略的想法,尝试实现类似的东西。
答案 1 :(得分:8)
花了2个小时,挖掘谷歌和Laravel的源代码后,我想出了这个解决方案,我觉得这个解决方案效果最好,看起来最干净。无需重定向和多个内部请求。
您可以在路径文件的最底部添加此路线。 如果没有匹配其他路由,则执行此操作。在闭包中,您可以决定执行哪个控制器和操作。 最好的部分是 - 所有路由参数都传递给action,方法注入仍然有效。 ControllerDispatcer行来自Laravel Route(r?)类。
我的例子将处理2个案例 - 首先检查用户是否存在该名称,然后检查slug是否可以找到文章。
Laravel 5.2(5.3以下)
Route::get('{slug}/{slug2?}', function ($slug) {
$class = false;
$action = false;
$user = UserModel::where('slug', $slug)->first();
if ($user) {
$class = UserController::class;
$action = 'userProfile';
}
if (!$class) {
$article= ArticleModel::where('slug', $slug)->first();
if ($article) {
$class = ArticleController::class;
$action = 'index';
}
}
if ($class) {
$route = app(\Illuminate\Routing\Route::class);
$request = app(\Illuminate\Http\Request::class);
$router = app(\Illuminate\Routing\Router::class);
$container = app(\Illuminate\Container\Container::class);
return (new ControllerDispatcher($router, $container))->dispatch($route, $request, $class, $action);
}
// Some fallback to 404
throw new NotFoundHttpException;
});
5.3改变了控制器的调度方式。
这是 5.3,5.4
的动态控制器示例namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Routing\ControllerDispatcher;
use Illuminate\Routing\Route;
class DynamicRouteController extends Controller
{
/**
* This method handles dynamic routes when route can begin with a category or a user profile name.
* /women/t-shirts vs /user-slug/product/something
*
* @param $slug1
* @param null $slug2
* @return mixed
*/
public function handle($slug1, $slug2 = null)
{
$controller = DefaultController::class;
$action = 'index';
if ($slug1 == 'something') {
$controller = SomeController::class;
$action = 'myAction';
}
$container = app();
$route = $container->make(Route::class);
$controllerInstance = $container->make($controller);
return (new ControllerDispatcher($container))->dispatch($route, $controllerInstance, $action);
}
}
希望这有帮助!
答案 2 :(得分:2)
尝试
Route::get('/', ['as' => 'home', 'uses' => 'HomeController@index']);
$pages =
Cache::remember('pages', 5, function() {
return DB::table('pages')
->where('status', 1)
->lists('slug');
});
if(!empty($pages))
{
foreach ($pages as $page)
{
Route::get('/{'.$page.'}', ['as' => $page, 'uses' => 'PagesController@show']);
}
}
答案 3 :(得分:2)
我们可以通过这种方式进行动态路线
// Instanciate a router class.
$router = app()->make('router');
从数据库获取路由值
// For route path this can come from your database.
$paths = ['path_one','path_two','path_three'];
然后迭代该值以创建动态路线
// Then iterate the router "get" method.
foreach($paths as $path){
$router->resource($path, 'YourController');
}
您还可以使用GET | POST | PUT | PATCH | DELETE方法
// Then iterate the router "get" method.
foreach($paths as $path){
$router->get($path, 'YourController@index')->name('yours.index');
}
答案 4 :(得分:0)
有一个可用的组件,可用于在数据库中存储路由。另外一个优点是,该组件仅加载当前的活动路由,因此由于并非所有路由都已加载到内存中,因此可以提高性能。
https://github.com/douma/laravel-database-routes
按照自述文件中提供的安装说明进行操作。
在数据库中存储路由
这里唯一需要做的就是将RouteManager
注入到cli命令中。使用addRoute
可以告诉RouteManager
将路由存储到数据库中。您可以轻松地更改此代码,并使用自己的页面存储库或其他数据来构造路线。
use Douma\Routes\Contracts\RouteManager;
class RoutesGenerateCommand extends Command
{
protected $signature = 'routes:generate';
private $routeManager;
public function __construct(RouteManager $routeManager)
{
$this->routeManager = $routeManager;
}
public function handle()
{
$this->routeManager->addRoute(
new Route('/my-route', false, 'myroute', MyController::class, 'index')
);
}
}
每2-5分钟或在更改数据后运行此cli命令,以确保路由是最新的。
在App \ Http \ Kernel.php中注册RouteMiddleware
\Douma\Routes\Middleware\RouteMiddleware::class
清空您的web.php
如果定义了任何Laravel路由,请确保清空此文件。
使用来自数据库的路由
您可以在刀片中使用该路线:
{{ RouteManager::routeByName('myroute')->url() }}
或者您可以将RouteManager
接口注入任何您想要获得路线的位置:
use Douma\Routes\Contracts\RouteManager;
class MyClass
{
public function __construct(RouteManager $routeManager)
{
$this->routeManager = $routeManager;
}
public function index()
{
echo $this->routeManager->routeByName('myroute')->url();
}
}
有关更多信息,请参见自述文件。
答案 5 :(得分:0)
你可以做这样的事情。非常适合我
use Illuminate\Container\Container;
use Illuminate\Routing\ControllerDispatcher;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Illuminate\Routing\Route as MainRoute;
use Illuminate\Routing\Router;
Route::group([
'prefix' => config('app.payment.route_prefix'),
'namespace' => config('app.payment.route_namespace'),
'middleware' => config('app.payment.route_middleware')
], function (Router $router) {
/**
* Resolve target payment method controller
*
* @param $key Example key [paypal]
* @param $action
* @return mixed
*/
$resolver = function ($key, $action) {
$route = app(MainRoute::class);
$container = app(Container::class);
// Generate App\\Http\Controllers\PaymentMethods\PaypalController
$controller = app(sprintf('%s\\%sController', config('app.payment.route_namespace'), ucfirst($key)));
return (new ControllerDispatcher($container))->dispatch($route, $controller, $action);
};
$router->post('{key}/error', function ($key) use ($resolver) {
return $resolver($key, 'error');
});
$router->post('{key}/success', function ($key) use ($resolver) {
return $resolver($key, 'success');
});
$router->get('{key}', function ($key) use ($resolver) {
return $resolver($key, 'index');
});
});