Laravel – как передать параметр маршруту? Есть ли более эффективная практика?

Упрощенный сценарий следующий:

У меня есть несколько страниц в базе данных (в идеале не более 10-20, но жестких ограничений нет). У всех у них есть контент и «слизняк» (есть пули, которые содержат косую черту, если это имеет значение). Я пытаюсь зарегистрировать маршрут (ы) к этим слизнякам на PageController который отображает содержимое данной страницы. Вот мои идеи о подходе:

  • Зарегистрируйте один «поймать все» маршрут (который должен быть самым последним зарегистрированным маршрутом). Это определенно плохо.
  • Запросите все ссылки из базы данных и зарегистрируйте для них отдельные маршруты. Это легко, но я должен запросить БД (что может быть не оптимальным) и зарегистрировать десятки, потенциально сотни маршрутов.
  • То, что я также пробовал: зарегистрировать промежуточное ПО HTTP, получить параметр запроса с помощью $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... } 

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