Apache下.htaccess规则必须用index.php?/$1而非index.php/$1,因后者会丢失查询参数;Nginx需配置fastcgi_param PATH_INFO $fastcgi_path_info;路由分隔符须与pathinfo_depr一致;url_html_suffix影响参数解析,建议调试时关闭。

Apache下.htaccess规则必须用index.php?/$1,不是index.php/$1
TP5 默认依赖 $_SERVER['PATH_INFO'] 解析参数,但 Apache 的 RewriteRule ^(.*)$ index.php/$1 写法在部分版本中会丢掉查询参数(如 ?id=123),导致路由匹配失败或参数为空。
正确写法是末尾带问号:index.php?/$1,它能确保原始 URL 中的 query string 被保留并传入 PHP:
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
-
QSA(Query String Append)保证原有参数不丢失 -
PT(PassThrough)让重写结果继续被 PHP 处理,而非返回 404 - 确认 Apache 已启用
mod_rewrite,且站点配置中AllowOverride至少为FileInfo
Nginx必须补全fastcgi_param PATH_INFO $fastcgi_path_info
TP5 启动时若报 URL pathinfo not supported,基本就是 Nginx 没传递 PATH_INFO。Nginx 默认不设置该变量,框架无法解析 /article/123 这类路径中的参数。
在 location ~ \.php$ 块里,必须显式添加这一行:
立即学习“PHP免费学习笔记(深入)”;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
- 缺了这句,
$_SERVER['PATH_INFO']为空,所有带参数的伪静态路由(如article/:id)都会 404 - 注意:
$fastcgi_path_info是 Nginx 内置变量,需搭配try_files或正则匹配才能正确提取 - 如果入口是
public/index.php(TP5.1+),$document_root必须指向public/目录,否则SCRIPT_FILENAME错误
路由定义要匹配pathinfo_depr分隔符,别硬写/
TP5 默认用 / 分割 PATH_INFO(如 /article/123),但如果你改过 pathinfo_depr 配置(比如设成 -),路由规则就必须同步调整,否则参数根本进不来。
例如,在 config/app.php 中设了:
'pathinfo_depr' => '-',
那对应路由就得写成:
Route::rule('article-<id>', 'index/article/read');
- 访问
/article-123才能命中,/article/123会 404 - 控制器方法签名也得对齐:
public function read($id) { ... } - 别在路由里混用分隔符,比如
article/<id></id>+pathinfo_depr'=>'-'—— 这种组合永远不生效
url_html_suffix影响参数解析顺序,后缀不能随便加
开启后缀(如 'url_html_suffix' => '.html')后,TP5 会把后缀前的部分当作完整 PATH_INFO,而把后缀本身剥离后存入 Request::ext()。
这意味着:
- URL
/article/123.html→ PATH_INFO 是/article/123,ext()返回html - URL
/article/123.pdf→ 若未在url_html_suffix中声明pdf,框架会直接报错 - 若设成
'url_html_suffix' => 'html|xml|pdf',则三者都可接受,但参数解析逻辑不变 - 若后缀不在白名单里,比如访问
/article/123.xyz,框架会把123.xyz当作$id值传入,而不是报错——这是隐式降级行为,容易埋坑
实际调试时,建议先关掉后缀(url_html_suffix => false),确认参数路由跑通后再开,避免干扰判断。



















