Laravel从Mysql数据库创建动态路由到控制器

时间:2014-04-17 23:40:10

标签: php laravel laravel-4

我有下表: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');

6 个答案:

答案 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');
    });
});