Laravel Создание динамических маршрутов для контроллеров из базы данных Mysql

У меня есть следующая таблица: group_pages в базе данных mysql с именем имени страницы:

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

что я пытаюсь сделать, это создать динамические маршруты в моем: routes.php?

Где я могу перейти к примеру: /about он перейдет в AboutController.php (который будет создан динамически), возможно ли это? возможно ли создать файл динамического контроллера?

Я пытаюсь создать маршруты динамических страниц, которые ссылаются на контроллер

Например, я хочу сгенерировать это динамически в моем routes.php

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

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

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

Ответы

Ответ 1

Это не правильный способ создания динамических страниц, вы должны использовать базу данных и хранить все страницы в базе данных. Например:

// 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' => '[email protected]'));

Чтобы получить доступ к странице, вам может потребоваться url/link следующим образом:

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

Это приблизительная идея, попробуйте реализовать что-то вроде этого.

Ответ 2

Проведя 2 часа, вырываясь через источник google и Laravel, я придумал это решение, которое, я думаю, работает лучше всего и выглядит чище. Нет необходимости переадресации и нескольких внутренних запросов.

Вы добавляете этот маршрут в самую нижнюю часть файлов маршрутов. Если никакие другие маршруты не совпадают, это выполняется. В закрытии вы решаете, какой контроллер и какое действие выполнить. Наилучшая часть - все параметры маршрута передаются в действие, и инъекция метода все еще работает. Линия 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);
    }
}

Надеюсь, это поможет!

Ответ 3

попробуйте

Route::get('/', ['as' => 'home', 'uses' => '[email protected]']);

$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' => '[email protected]']);
   }
}

Ответ 4

Доступен компонент, который вы можете использовать для хранения маршрутов в базе данных. В качестве дополнительного преимущества этот компонент загружает только текущий активный маршрут, что повышает производительность, поскольку не все маршруты загружаются в память.

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

Следуйте инструкциям по установке, приведенным в файле readme.

Хранение маршрутов в базе данных

Единственное, что здесь необходимо, это ввести RouteManager например, в команду RouteManager. С помощью 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')
        );
    }
}

Выполняйте эту команду cli каждые 2-5 минут или после изменения ваших данных, чтобы убедиться, что маршруты обновлены.

Зарегистрируйте RouteMiddleware в App\Http\Kernel.php

\Douma\Routes\Middleware\RouteMiddleware::class

Очистите ваш web.php

Если вы определили какой-либо маршрут Laravel, обязательно очистите этот файл.

Использование маршрутов из базы данных

Вы можете использовать маршрут в Blade:

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

Или вы можете ввести 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();
    }
}

Для получения дополнительной информации см. Readme.