ThinkPHP路由默认不匹配中文参数是刻意的安全策略,因默认正则仅允许[a-zA-Z0-9_-]+;需显式用pattern()配合u修饰符及Unicode范围(如[\x{4e00}-\x{9fa5}a-zA-Z0-9_-]+)方可支持中文值。

中文参数默认不匹配,不是 bug 是安全策略
ThinkPHP 路由里写 {title} 却访问 /article/你好世界 返回 404,根本原因不是框架不支持中文,而是默认正则只放行 [a-zA-Z0-9_-]+ —— 中文、空格、点号、斜杠全被拦在门外。这不是疏漏,是刻意设计的安全兜底。
要支持中文必须显式加 pattern() 并带 u 修饰符
直接写 ->pattern(['title' => '.*']) 没用,.* 在 PCRE 里默认不匹配 Unicode 字符;也不要用 {title}.* 这种错误语法,占位符后不能拼正则。
-
Route::get('article/<title>', 'Article/read')->pattern(['title' => '[\x{4e00}-\x{9fa5}a-zA-Z0-9_-]+']);</title>✅(Unicode 中文范围 + 字母数字) -
Route::get('article/<title>', 'Article/read')->pattern(['title' => '.*']);</title>❌(.*缺u修饰符,中文仍失败) -
Route::get('article/{title:.*}', 'Article/read');❌(TP6+ 不支持内联{name:regex}写法,解析报错)
中文参数名本身不能含中文,但值可以
占位符名称(如 <title></title>)必须是合法 PHP 变量名,所以 或 会直接导致 PHP 解析失败或路由注册异常;但它的值(param('title') 拿到的内容)可以是中文,前提是上面的 pattern() 已正确放开。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- ✅ 正确:
Route::get('article/<title>', 'Article/read')->pattern(['title' => '[\x{4e00}-\x{9fa5}a-zA-Z0-9_-]+']);</title> - ❌ 错误:
Route::get('article/', 'Article/read')->pattern([...]);(PHP 语法错误) - ⚠️ 注意:
param('title')拿到的是 URL 解码后的原始字符串,若前端未 encodeURI,空格或特殊符号可能被截断
多字节字符还影响路由缓存和命令行工具
含中文的路由规则一旦写进 app/route/app.php,执行 php think route:list 时终端编码不对可能显示乱码;更严重的是,如果服务器环境 locale 不支持 UTF-8(比如某些 Docker 镜像默认 C locale),runtime/route.php 编译缓存会写入损坏的正则表达式,导致后续所有路由失效。
立即学习“PHP免费学习笔记(深入)”;
- 清缓存前先确认环境:
locale | grep UTF-8,没输出就运行export LANG=C.UTF-8 - 改完路由必须执行
php think route:clear,不能只删runtime/route.php文件 - Swoole 环境下修改含中文路由,必须重启服务,热重载不重新编译正则逻辑


















