Laravel Создание динамических маршрутов к контроллерам из базы данных Mysql
У меня есть следующая таблица: group_pages в базе данных MySQL с именем страницы имя маршрута:
id name route
--------------------
0 About about
1 Contact contact
2 Blog blog
что я пытаюсь сделать, это создать динамические маршруты в моем: rout.php?
Где, если я пойду к примеру: /about
это пойдет в AboutController.php
(который будет создан динамически) это возможно? Можно ли создать файл динамического контроллера?
Я пытаюсь создать динамические страницы маршрутов, которые ссылаются на контроллер
Пример, который я хочу генерировать это динамически в моем routes.php
Route::controller('about', 'AboutController');
Route::controller('contact', 'ContactController');
Route::controller('blog', 'BlogController');
6 ответов
Это неправильный способ создания динамических страниц, вы должны использовать базу данных и хранить все страницы в базе данных. Например:
// 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
Это грубая идея, попробуйте реализовать что-то вроде этого.
Потратив 2 часа, копаясь в источниках Google и Laravel, я пришел к этому решению, которое, я думаю, работает лучше всего и выглядит самым чистым. Нет необходимости в перенаправлениях и множественных внутренних запросах.
Вы добавляете этот маршрут в самом низу файлов маршрутов. Если никакие другие маршруты не совпадают, это выполняется. В закрытии вы решаете, какой контроллер и какое действие выполнить. Самое приятное то, что все параметры маршрута передаются в действие, а внедрение метода все еще работает. Линия ControllerDispatcer относится к классу Laravel Route(r?).
Мой пример будет обрабатывать 2 случая - сначала проверяет, существует ли пользователь с таким именем, а затем проверяет, может ли статья быть найдена слагом.
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);
}
}
Надеюсь это поможет!
Пытаться
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']);
}
}
Таким образом мы можем построить динамический маршрут
// 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');
}
Доступен компонент, который можно использовать для хранения маршрутов в базе данных. В качестве дополнительного преимущества этот компонент загружает только текущий активный маршрут, поэтому он повышает производительность, поскольку не все маршруты загружаются в память.
https://github.com/douma/laravel-database-routes
Следуйте инструкциям по установке, приведенным в файле readme.
Хранение маршрутов в базе данных
Единственное, что здесь нужно, - это ввести 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')
);
}
}
Выполняйте эту команду cli каждые 2–5 минут или после изменения данных, чтобы убедиться, что маршруты актуальны.
Зарегистрируйте RouteMiddleware в App\Http\Kernel.php
\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();
}
}
Для получения дополнительной информации см. Файл readme.
Вы можете сделать что-то подобное. Это работает идеально для меня
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');
});
});