Laravel - how to pass a parameter to a route? Is there a better practice?

心不动则不痛 提交于 2019-12-06 12:33:08

All approaches you've listed can be a valid approaches to solving this problem (even the first one if you attach a where condition on the route). However in my opinion the best approach, performance wise, would be based on the second solution, and would be to generate and write the routes to a file when needed and then caching them. So here's how I'd go about doing it:

Warning: This approach only works if you don't have any Closure based routes

1. Create a separate routes file where you'll be storing your page routes, let's say in app/Http/Routes/page.php. This is where you'll be writing the route definitions for your pages. You'll also need to add this to the map method of the App\Providers\RouteServiceProvider class:

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. Then you need to generate and write the route definitions for the pages to that file. Something like this should suffice:

$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');

The code above should be executed on specific events that you can attach to the Page model: created, deleted, updated (but only if the slug was modified during the update).

3. To access the page details in your controller you just need to use the path of the request, since that's your slug. So this would do:

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...
}

There you go, now you have route definitions for all your pages. And the fact that they're cached mitigates any performance penalties you would get when there are lots of routes and you're only touching the database when you are making changes to those routes, not on every request.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!