根据 URL 将额外参数传递给 PHP Laravel 控制器

问题描述 投票:0回答:3

我有竞赛网站,我在其中使用这样的网络路线:

Route::get('results/{year?}', 'Results')->where('year', '[0-9]+');

只需“破解”URL,即可偷偷了解当年“未发布”的结果。 我想每年创建自定义路线,因此在我想要发布结果后 - 我仅更改路线文件。在 Laravel 中可以吗?

我红色了 Laravel 文档并尝试搜索这个问题,但我无法找到我的问题的确切查询,因为还有很多其他带有额外参数的类似问题。

我尝试尝试可能的路线定义,比如这样,但不起作用:

Route::get('results_2023', 'Results', ['year' => 2023])->where('year', '[0-9]+');
Route::get('results_2024', 'Results', ['year' => 2024])->where('year', '[0-9]+');

我不想要的 - 它是重定向(URL 转换),因此任何使用 URL results_2025 的人都会被重定向到 results/2025,这是我想避免的。

php laravel url parameters controller
3个回答
0
投票

您可以使用

defaults
对象的
Route
方法来设置将传递给操作的默认参数:

Route::get('results_2023', 'Results')->defaults('year', 2023);

0
投票

我建议不要总是改变路线或控制器。但您可以在控制器的方法中添加自定义验证。

web.php

Route::get('results/{year}', [ResultController::class, 'result']);

ResultController.php

    public function result(Request $request, $year)
    {
        $validateYear = $this->validateResultYear($year);

        if ($validateYear->fails()) {
            return response()->json(['error' => $validateYear->errors()], 400);
        }

        // Validation passed, proceed with your logic
        switch ($year) {
            // ... switch cases based on year value
            // do something based on year
            // again use custom methods here per year if needed so that code is cleaner
        }

        // Return response or render view
    }

    public function validateResultYear($year)
    {
        // rules
        $rules = [
            'year' => 'required|integer|min:1900|max:2100', // adjust rules
        ];

        // messages
        $messages = [
            'year.required' => 'The year is required.',
            'year.integer' => 'The year must be an integer.',
            'year.min' => 'The year must be at least :min.',
            'year.max' => 'The year must not be greater than :max.',
        ];

        // create new request with year param
        $request = new Request(['year' => $year]);

        // validate
        $validator = \Validator::make($request->all(), $rules, $messages);

        return $validator;
    }

没有测试代码,但它应该足以让您编辑并获得您想要的结果。


0
投票

正如其他答案所提到的,您可以使用

defaults
方法将参数值从路由传递到控制器。

但还有一点, 假设你的控制器中有

public function index( Request $request, $year ) {
    return [
        'year' => $year
   ];
} 

您应该删除可选年份

// only support year from 2000 - 2023, add 19\d{2} if you want to support year from 1900-1999
Route::get('results/{year}', [Result::class, 'index'])
    ->where('year', '(20[01]\d|202[0-3])'); 

或者可以选择年份,但如果您希望

/results
有默认年份

,请提供默认值
Route::get('results/{year?}', [Result::class, 'index'])
    ->where('year', '(20[01]\d|202[0-3])')
    ->defaults('year', now()->format('Y') );

对于没有年份参数的其他路线,只需提供默认年份值即可

Route::get('results_2023', [Result::class, 'index'])->defaults('year', 2023);
Route::get('results_2024', [Result::class, 'index'])->defaults('year', 2024);
© www.soinside.com 2019 - 2024. All rights reserved.