需启用路由强制模式,即设'url_route_must'=>true并清空runtime/route目录;若仍可访问m/c/a参数URL,须在app_init事件中添加input校验拦截;子域名路由须独立注册且配置url_domain_deploy=>true。

如果您在ThinkPHP项目中希望所有URL请求都必须匹配预定义的路由规则,否则直接返回404错误,则需启用路由强制模式。该模式可有效阻止未授权的模块/控制器/操作(m/c/a)参数式访问,提升应用安全性。以下是具体配置与验证步骤:
一、修改全局路由配置项
路由强制模式由配置项 url_route_must 控制,设为 true 后,框架将跳过隐式路由匹配,仅响应 route.php 中明确定义的规则。
1、打开 config/route.php 文件(ThinkPHP 5.x)或 app/config/app.php 中的 route 配置块(ThinkPHP 6.x)。
2、确认已存在并启用以下配置:
'url_route_must' => true
立即学习“PHP免费学习笔记(深入)”;
3、同时确保 'url_route_on' => true 已开启,否则路由系统整体不生效。
二、清除路由运行时缓存
ThinkPHP会将路由规则编译后缓存至 runtime/route/ 目录。若仅修改配置但未清理缓存,旧规则仍被加载,导致强制模式看似未生效。
1、进入项目根目录下的 runtime/route/ 路径。
2、**彻底删除整个 route 文件夹**,而非仅清空其内容。
3、重新发起任意请求,触发框架重建缓存文件。
三、验证强制模式是否生效
启用后,未在路由定义中声明的路径将不再回退至默认的 index.php?m=xxx&c=yyy&a=zzz 解析逻辑,而是立即中断并抛出 404 异常。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
1、尝试访问一个未定义的URL,例如 http://localhost/index.php/test/unknown。
2、观察响应状态码是否为 404,且页面内容为 Route not found 或自定义的 404 提示。
3、若仍能访问控制器方法(如 index.php?m=index&c=index&a=index),说明缓存未清除或配置未正确加载。
四、补充拦截 m/c/a 参数的硬性校验
仅依赖 url_route_must 可能不足以完全阻断带 m、c、a 参数的请求,尤其当路由规则存在动态变量或闭包时,框架底层仍可能解析这些参数。
1、在应用初始化事件(如 app/common.php 或注册为 app_init 事件监听器)中插入校验代码。
2、添加如下判断逻辑:
if (input('m') || input('c') || input('a')) { throw new \think\exception\HttpException(404, 'Direct module/controller/action access denied'); }
3、确保该代码执行时机早于路由匹配流程,否则拦截无效。
五、检查子域名与泛域名路由注册方式
在强制模式下,主域名与子域名的路由规则互不继承,必须独立注册。若使用子域名(如 admin.example.com)或泛域名(*.example.com),其内部路由需在对应域名闭包内完整重写。
1、确认 url_domain_deploy 配置为 true(泛域名场景必需)。
2、子域名路由必须使用 Route::domain() 显式包裹,并在其中重新定义全部所需规则,不可复用全局 Route::get()。
3、本地开发时,若测试子域名,须在系统 hosts 文件中添加对应解析记录,例如:
127.0.0.1 admin.localhost


















