在ThinkPHP 8中,设置动态路由接收参数有多种方式。以下是几种常见的方法:

方法1:使用路由定义文件(推荐)

1. 创建路由文件

route 目录下创建 app.php 或直接在已有文件中添加:

// route/app.php
use think\facade\Route;

// 方式1:基础路由定义
Route::get('test/:id.html', 'Test/index');

// 方式2:指定控制器和方法
Route::get('test/:id.html', 'app\controller\Test/index');

// 方式3:使用完整类名
Route::get('test/:id.html', [app\controller\Test::class, 'index']);

// 方式4:添加路由名称(便于生成URL)
Route::get('test/:id.html', 'Test/index')->name('test.detail');

2. 控制器中接收参数

// app/controller/Test.php
namespace app\controller;

class Test
{
    // 方法1:通过方法参数接收
    public function index($id)
    {
        return '接收到的ID是:' . $id;
    }
    
    // 方法2:通过Request对象接收
    public function detail()
    {
        // 获取路由参数
        $id = request()->param('id');
        // 或者
        $id = request()->route('id');
        
        return 'ID:' . $id;
    }
}

方法2:使用路由规则配置

config/route.php 中配置路由规则

// config/route.php
return [
    // 路由规则
    'rule' => [
        // 定义路由规则
        'test/<id>.html' => 'Test/index',
    ],
];

方法3:使用注解路由(需要安装注解路由扩展)

1. 安装注解路由扩展

composer require topthink/think-annotation

2. 在控制器中使用注解

// app/controller/Test.php
namespace app\controller;

use think\annotation\Route;

class Test
{
    /**
     * @Route("test/:id.html")
     */
    public function index($id)
    {
        return 'ID:' . $id;
    }
}

方法4:添加参数约束

1. 正则约束

// route/app.php
use think\facade\Route;

// 限制id必须为数字
Route::get('test/:id.html', 'Test/index')
    ->pattern(['id' => '\d+']);

// 或者使用更复杂的正则
Route::get('test/:id.html', 'Test/index')
    ->pattern(['id' => '[A-Za-z0-9]+']);

2. 类型约束

// 自动类型转换
Route::get('test/:id.html', 'Test/index')
    ->pattern(['id' => '\d+'])
    ->ext('html');  // 设置URL后缀

// 设置默认值
Route::get('test/[:id].html', 'Test/index')
    ->pattern(['id' => '\d+'])
    ->default(['id' => 1]);  // 设置默认值

方法5:路由分组

// route/app.php
use think\facade\Route;

Route::group('test', function() {
    // /test/1.html
    Route::get(':id.html', 'Test/index');
    
    // /test/1/edit.html
    Route::get(':id/edit.html', 'Test/edit');
    
    // /test/1/update.html
    Route::post(':id/update.html', 'Test/update');
})->pattern(['id' => '\d+']);  // 分组统一约束

完整示例

1. 路由定义

// route/app.php
use think\facade\Route;

// 定义带参数约束的路由
Route::get('test/:id.html', [app\controller\Test::class, 'index'])
    ->name('test.index')
    ->pattern(['id' => '\d+'])
    ->ext('html');

2. 控制器

// app/controller/Test.php
namespace app\controller;

use think\Request;

class Test
{
    public function index(Request $request, $id)
    {
        // 获取参数的方式
        $id1 = $id;                    // 方法参数直接获取
        $id2 = $request->param('id');  // Request对象获取
        $id3 = input('id');           // 助手函数获取
        
        // 返回数据
        return json([
            'id' => $id,
            'method' => $request->method(),
            'all_params' => $request->param()
        ]);
    }
    
    public function create()
    {
        // 生成URL
        $url1 = url('test/index', ['id' => 1]);  // 使用助手函数
        $url2 = route('test.index', ['id' => 1]); // 使用路由名称
        
        return '创建页面';
    }
}

3. 访问示例

  • 访问:/test/123.html
  • 控制器接收到的 $id 值为:123

注意事项

  1. 路由优先级:路由定义从上到下匹配,先定义的优先级高
  2. 混合模式:ThinkPHP 8默认开启强制路由,需要在 config/route.php 中设置:
'url_route_must' => true,  // 强制使用路由
  1. URL生成
// 使用路由名称生成URL
url('test.detail', ['id' => 123, 'ext' => 'html']);

// 结果:/test/123.html
  1. 参数获取顺序:路由参数优先级高于GET和POST参数

这样设置后,你就可以通过 /test/1.html/test/2.html 等形式访问,并且控制器能正确接收到变化的id参数。