必须用Route::rule()实现伪静态路由,Route::get()和Route::alias()不支持后缀匹配与正则提取;如需匹配/article/123.html,应写Route::rule('article/:id\.html', 'index/article/read'),并配合url_route_must=>true和服务器重写规则确保PATH_INFO正确传递。

ThinkPHP5自定义路由绑定必须用Route::rule(),别混用alias或get
自定义伪静态路由(比如把/article/123.html映射到index/article/read)不能靠Route::alias()或Route::get()实现——前者只做路径别名跳转,后者强制限定请求方法且不处理后缀匹配逻辑。Route::rule()才是唯一支持完整正则、参数提取和后缀控制的入口。
常见错误是写成:Route::get('article/:id', 'index/article/read'),结果/article/123.html 404,但/article/123能通。这是因为get不解析.html后缀,也不自动剥离它。
-
Route::rule('article/:id\.html', 'index/article/read')才正确匹配带.html的 URL - 如果想同时兼容无后缀访问,得写两条:
Route::rule('article/:id', 'index/article/read')和Route::rule('article/:id\.html', 'index/article/read') - 注意反斜杠转义:
\.html中的点必须加\,否则会被当作通配符
后缀强制校验要靠url_html_suffix + 路由规则双重控制
光在config/app.php里设'url_html_suffix' => '.html',只是让框架生成链接时自动加.html,并不阻止用户直接访问不带后缀的地址。要真正“绑死”后缀,必须在路由规则里显式声明并配合url_route_must => true。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 开启严格路由:
'url_route_must' => true,否则未定义的路径会 fallback 到默认模块/控制器 - 路由规则中必须包含字面量后缀,如
'news/:id\.html',不能只写'news/:id' - 若需统一拦截非
.html请求,可加中间件判断request()->url()是否匹配/\.html$/,不匹配直接exit或抛异常
Apache下.htaccess必须放在public/目录,且重写目标要带index.php
TP5入口文件是public/index.php,所有重写最终都要落到它身上。很多人把.htaccess放错位置或写错目标,导致路由根本没机会执行。
立即学习“PHP免费学习笔记(深入)”;
-
.htaccess必须放在public/目录下,不是项目根目录(含application那层) - 规则里
RewriteRule的目标必须是index.php,例如:RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] - 若用
try_files方式(Nginx),也要确保/index.php?s=$uri&$args中的s参数被正确传递,否则PATH_INFO为空,路由无法解析 - Apache需确认
AllowOverride All作用于public/目录,且rewrite_module已启用
调试时先看request()->pathinfo()输出,再查$_SERVER['PATH_INFO']
伪静态失败,90% 是PATH_INFO没拿到值,导致路由层收不到原始路径。不要一上来就改路由规则,先验证底层是否通。
- 在控制器里加
dump(request()->pathinfo()); die;,访问/article/123.html,看输出是不是article/123.html - 如果不是,检查
$_SERVER['PATH_INFO']是否为空;空的话说明服务器没传过来,问题出在.htaccess或 Nginx 配置 - 如果
pathinfo()有值但路由不匹配,再回头核对Route::rule()里的正则是否漏转义、变量名是否和:id一致、大小写是否匹配
index.php → 框架从PATH_INFO提取pathinfo → Route::rule()按正则匹配并分发。少一环,自定义路由就悬在半空。


















