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.