Laravel - 如何将参数传递给路线?有更好的做法吗?

时间:2016-02-17 18:23:17

标签: php laravel laravel-5 laravel-5.2

简化方案如下:

我在数据库中有几页(理想情况下不超过10-20,但没有硬限制)。它们都有一些内容和一个“slu”“(如果重要的话,有一些包含正斜杠的slu))。我正在尝试将这些段落的路由注册到显示给定页面内容的PageController。以下是我对该方法的看法:

  • 注册一个“catch'em all”路线(应该是最后注册的路线)。这绝对是坏事。
  • 查询数据库中的所有链接并注册到它们的各个路由。这很容易,但我必须查询数据库(这可能不是最佳的)并注册数十个,可能有数百个路由。
  • 我还尝试过:注册HTTP中间件,使用$request->path()获取查询参数,检查这是否是现有的slug,如果是,请将其传递给PageController。我通过简单地调用Route::get($request->path(), 'PageController@show')来实现这一目标。

最后两种方法似乎都有效,但有一个问题:如何告诉Controller要显示哪个页面?

还是有更好的方法吗?

提前致谢

编辑:我绝对不想使用'前缀'并将slug作为参数添加到其中。定义的slug应该是页面的确切URL。

1 个答案:

答案 0 :(得分:3)

您列出的所有方法都可以成为解决此问题的有效方法(如果您在路线上附加where条件,则即使是第一个方法)。但是在我看来,最好的方法,性能方面,将基于第二个解决方案,并将在需要时生成并写入路由到文件,然后缓存它们。所以这就是我要做的事情:

  

警告:此方法仅在您没有任何基于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模型的特定events上执行:createddeletedupdated(但仅限于在更新期间修改了slu。)。

3. 要访问控制器中的页面详细信息,您只需使用请求的path,因为这是您的slug。所以这样做:

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

你去了,现在你有了所有页面的路线定义。并且它们被缓存的事实减轻了当有很多路由时你会得到的任何性能损失,并且当你对这些路由进行更改而不是每次请求时都只触及数据库。