隐藏index.php需Web服务器伪静态配置:Apache须启用mod_rewrite、AllowOverride All,并将.htaccess置于public目录;Nginx需在location /和location ~.php$中均配置try_files,且root必须指向public目录。

隐藏 index.php 不是 ThinkPHP 自己能“关掉”的功能,而是必须由 Web 服务器把所有非静态请求统一转发给 index.php 入口文件处理。没配好伪静态规则,路由就根本收不到请求,必然 404。
Apache 下 .htaccess 不生效的常见原因
ThinkPHP 自带的 .htaccess 文件放在 public/ 目录下,但多数情况下它压根不运行——因为 Apache 默认禁用目录级重写。
- 检查
httpd.conf或虚拟主机配置中是否启用了mod_rewrite.so模块(去掉#LoadModule rewrite_module modules/mod_rewrite.so前的注释) -
AllowOverride必须设为All,不能是None或FileInfo;如果用了虚拟主机,<Directory>块里也要明确写上 -
.htaccess必须放在public/目录(即index.php所在目录),不是项目根目录 - Apache 用户(如
www-data)需对.htaccess有读取权限,否则静默忽略
推荐使用这个精简版规则(兼容 TP6/TP8):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?s=$1 [QSA,L]
</IfModule>
Nginx 中 location ~ .php$ 块漏配 try_files 导致 502/404
只在 location / 里加 try_files 是不够的。当请求最终落到 PHP 处理块时,Nginx 会按字面匹配 .php 文件——而 /user/login 并不是真实 PHP 文件,不加兜底就会直接 404 或报 No input file specified。
立即学习“PHP免费学习笔记(深入)”;
- 务必在
location ~ .php$块内也写try_files $uri =404;或更稳妥的try_files $uri /index.php?$query_string; -
root必须指向public/目录,例如root /var/www/myapp/public;;否则$document_root/index.php会路径错误 - 不要用
rewrite+last替代try_files,前者容易循环或覆盖失败 - 云服务器(如腾讯云轻量)自带的默认 Nginx 配置常含预设
location ~ .php$,要检查是否被你写的location /覆盖或冲突
标准写法示例(server 块内):
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
ThinkPHP 自身配置只需确保路由开启
TP6/TP8 默认已开启路由,不需要手动设 'url_route_on' => true;但以下几项仍需核对:
-
config/app.php中'app_host' => '',避免域名强制跳转干扰重写 - 不要设
'pathinfo_depr' => '\'这种 Windows 风格分隔符,Linux 服务器会解析失败 - TP6+ 完全依赖
s=参数传入路由,PATH_INFO模式已废弃,别再折腾fastcgi_split_path_info - 若用了子目录部署(如
https://example.com/myapp/),Nginx 的try_files要写成/myapp/index.php?$query_string,且root仍指到public/上层
测试与排错:404 时先看请求有没有进到 index.php
最直接的验证方式:临时在 public/index.php 开头加一行 file_put_contents('/tmp/hit.log', $_SERVER['REQUEST_URI'] . "
", FILE_APPEND);,然后访问一个路由地址(如 /user/list)。
- 如果日志里没记录,说明 Nginx/Apache 根本没把请求转过来——问题 100% 在服务器配置
- 如果日志有记录,但页面还是 404,说明框架内部路由没匹配上——检查域名绑定、模块名拼写、
Route::get()是否注册、应用目录是否正确 - Chrome 开发者工具 Network 标签页看响应状态码和响应头:
X-Powered-By: ThinkPHP出现了,说明已进框架;没出现,说明卡在 Web 服务器层
真正容易被忽略的是:Nginx 的 root 和 fastcgi_param SCRIPT_FILENAME 必须严格对齐,差一个字符或斜杠都会导致 File not found;而 Apache 的 AllowOverride All 往往被写在错误的 <Directory> 范围里,导致 .htaccess 形同虚设。



















