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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23145245/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 16:31:54  来源:igfitidea点击:

Laravel Creating Dynamic Routes to controllers from Mysql database

phplaravellaravel-4

提问by user3150060

I have the following table: group_pages in mysql database with page name route name :

我有下表: mysql 数据库中的 group_pages 页面名称路由名称:

   id   name      route
  --------------------
    0   About      about
    1   Contact    contact
    2   Blog       blog

what I am trying to do is to create dynamic routes in my : routes.php ?

我想要做的是在我的 : routes.php 中创建动态路由?

Where if I go to for example: /aboutit will go to AboutController.php( which will be created dynamically) is that possible? is it possible to create a dynamic controller file?

例如,如果我去哪里:/about它会去AboutController.php(将动态创建)这可能吗?是否可以创建动态控制器文件?

I am trying to create dynamic pages routes that links to a controller

我正在尝试创建链接到控制器的动态页面路由

example i want to generate this dynamically in my routes.php

例如我想在我的动态生成这个 routes.php

Route::controller('about', 'AboutController');

Route::controller('contact', 'ContactController');

Route::controller('blog', 'BlogController');

回答by The Alpha

This is not the right way to create dynamic pages instead, you should use a database and keep all pages in the database. For example:

这不是创建动态页面的正确方法,您应该使用数据库并将所有页面保存在数据库中。例如:

// Create pages table for dynamic pages
id | slug | title | page_content 

Then create PageEloquentmodel:

然后创建PageEloquent模型:

class Page extends Eloquent {
    // ...
}

Then create Controllerfor CRUD, you may use a resourcecontroller or a normal controller, for example, normally a PageController:

然后创建 Controllerfor 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);
    }
}

The views/page/index.blade.phpview file:

views/page/index.blade.php视图文件:

@extends('layouts.master')
{{-- Add other parts, i.e. menu --}}
@section('content')
    {{ $page->page_content }}
@stop

To show pages create a route like this:

要显示页面,请创建如下路线:

// could be page/{slug} or only slug
Route::get('/{slug}', array('as' => 'page.show', 'uses' => 'PageController@show'));

To access a page, you may require url/linklike this:

要访问页面,您可能需要url/link这样的:

http://example.com/home
http://example.com/about

This is a rough idea, try to implement something like this.

这是一个粗略的想法,尝试实现这样的东西。

回答by Mārti?? Briedis

After spending 2 hours, digging through google and Laravel source, I came up with this solution, which I think works the best and looks the cleanest. No need for redirects and multiple inner requests.

花了 2 个小时,通过 google 和 Laravel 源代码挖掘后,我想出了这个解决方案,我认为它效果最好,看起来最干净。不需要重定向和多个内部请求。

You add this route at the very bottom of routes files. If no other routes are matched, this is executed. In the closure, you decide which controller and action to execute. The best part is - all route parameters are passed to action, and method injection still works. The ControllerDispatcer line is from Laravel Route(r?) class.

您在路由文件的最底部添加此路由。如果没有其他路由匹配,则执行此操作。在闭包中,您决定执行哪个控制器和操作。最好的部分是 - 所有路由参数都传递给操作,并且方法注入仍然有效。ControllerDispatcer 行来自 Laravel Route(r?) 类。

My example would handle 2 cases - first checks if user exists by that name, then checks if an article can be found by the slug.

我的示例将处理 2 种情况 - 首先检查用户是否以该名称存在,然后检查是否可以通过 slug 找到文章。

Laravel 5.2 (5.3 below)

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 has changed how the controller gets dispatched.

5.3 改变了控制器的调度方式。

Heres my dynamic controller example for 5.3, 5.4

这是我的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);
    }
}

Hope this helps!

希望这可以帮助!

回答by Ali Elsayed Salem

try

尝试

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

回答by Pawan Kumar

We can make dynamic route by this way

我们可以通过这种方式制作动态路线

// Instanciate a router class.
$router = app()->make('router');

Get Route value from Database

从数据库中获取路由值

// For route path this can come from your database.
$paths = ['path_one','path_two','path_three'];

Then iterate the value to make dynamic route

然后迭代该值以制作动态路由

// Then iterate the router "get" method.
foreach($paths as $path){
    $router->resource($path, 'YourController');
}

You can use GET|POST|PUT|PATCH|DELETE methods also

您也可以使用 GET|POST|PUT|PATCH|DELETE 方法

// Then iterate the router "get" method.
foreach($paths as $path){
    $router->get($path, 'YourController@index')->name('yours.index');
}

回答by Douma

There is a component available, which you can use to store routes in a database. As an extra advantage, this component only loads the current active route, so it improves performance, since not all routes are loaded into the memory.

有一个可用的组件,您可以使用它在数据库中存储路由。作为一个额外的优势,这个组件只加载当前活动的路由,因此它提高了性能,因为不是所有的路由都加载到内存中。

https://github.com/douma/laravel-database-routes

https://github.com/douma/laravel-database-routes

Follow the installation instructions provided in the readme.

按照自述文件中提供的安装说明进行操作。

Storing routes in the database

在数据库中存储路由

The only thing needed here is injecting the RouteManagerinto for example a cli command. With addRoutecan tell the RouteManagerto store the route into the database. You can easily change this code and use your own repository of pages or other data to construct the 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')
        );
    }
}

Run this cli command every 2-5 minutes or after a change in your data to make sure the routes are recent.

每 2-5 分钟或在数据更改后运行此 cli 命令以确保路由是最新的。

Register the RouteMiddleware in App\Http\Kernel.php

在 App\Http\Kernel.php 中注册 RouteMiddleware

\Douma\Routes\Middleware\RouteMiddleware::class

\Douma\Routes\Middleware\RouteMiddleware::class

Empty your web.php

清空你的 web.php

If you have defined any Laravel route, make sure to empty this file.

如果您定义了任何 Laravel 路由,请确保清空此文件。

Using routes from the database

使用数据库中的路由

You can use the route in blade:

您可以在刀片中使用路由:

{{ RouteManager::routeByName('myroute')->url() }}

Or you can inject the RouteManager-interface anywhere you like to obtain the route:

或者你可以在RouteManager任何你喜欢的地方注入-interface 来获取路由:

use Douma\Routes\Contracts\RouteManager;
class MyClass
{
    public function __construct(RouteManager $routeManager) 
    {
        $this->routeManager = $routeManager;
    }

    public function index()
    {
        echo $this->routeManager->routeByName('myroute')->url();
    }
}

For more information see the readme.

有关更多信息,请参阅自述文件。