Упрощенный сценарий следующий:
У меня есть несколько страниц в базе данных (в идеале не более 10-20, но жестких ограничений нет). У всех у них есть контент и «слизняк» (есть пули, которые содержат косую черту, если это имеет значение). Я пытаюсь зарегистрировать маршрут (ы) к этим слизнякам на PageController
который отображает содержимое данной страницы. Вот мои идеи о подходе:
$request->path()
, проверить, является ли это существующим сливом, и если да, передайте его на PageController
. Я достигаю этого, просто вызывая Route::get($request->path(), 'PageController@show')
. Оба из последних двух методов, похоже, работают, но возникает вопрос: как я могу сообщить диспетчеру, какую страницу выложить?
Или есть лучший подход?
заранее спасибо
Изменить : я определенно не хочу использовать «префикс» и добавить в него параметр slug. Определенный пул должен быть точным URL-адресом на странице.
Все подходы, которые вы указали, могут быть действительными подходами к решению этой проблемы (даже первой, если вы приложите условие на маршруте). Однако, на мой взгляд, лучший подход, основанный на производительности, будет основан на втором решении и будет генерировать и писать маршруты в файл по мере необходимости, а затем кэшировать их. Итак, вот как я это сделаю:
Предупреждение. Этот подход работает только в том случае, если у вас нет маршрутов на основе Closure
1. Создайте отдельный файл маршрутов, в котором вы будете хранить маршруты страниц, скажем, в app/Http/Routes/page.php
. Здесь вы будете писать определения маршрутов для своих страниц. Вам также необходимо добавить это к методу map
класса App\Providers\RouteServiceProvider
:
public function map(Router $router) { $router->group(['namespace' => $this->namespace], function ($router) { require app_path('Http/routes.php'); require app_path('Http/Routes/page.php'); }); }
2. Затем вам нужно создать и написать определения маршрутов для страниц в этот файл. Что-то вроде этого должно быть достаточно:
$path = app_path('Http/Routes/page.php'); $definition = "Route::get('%s', 'PageController@show');\n"; // Remove the routes file so you can regenerate it if (File::exists($path)) { File::delete($path); } // Write the new routes to the file foreach (App\Page::all() as $page) { File::append(sprintf($definition, $page)); } // Rebuild Laravel's route cache so it includes the changes Artisan::call('route:cache');
Вышеприведенный код должен быть выполнен для определенных событий , которые можно присоединить к модели Page
: created
, deleted
, updated
(но только в том случае, если slug был изменен во время обновления).
3. Чтобы получить доступ к деталям страницы в вашем контроллере, вам просто нужно использовать path
запроса, так как это ваш пуля. Так это и сделало бы:
public function show(Request $request) { // You need to prepend the slash for the condition since // the path() method returns the request path without one $page = App\Page::where('slug', '/' . $request->path())->get(); // Do your stuff... }
Там вы идете, теперь у вас есть определения маршрута для всех ваших страниц. И тот факт, что они кэшируются, смягчает любые штрафы за производительность, которые вы получите, когда есть много маршрутов, и вы касаетесь базы данных только при внесении изменений в эти маршруты, а не по каждому запросу.