伪静态规则不写在ThinkPHP代码中,而是由Web服务器配置:Apache需在public目录下创建.htaccess文件并启用mod_rewrite与AllowOverride,含RewriteEngine On、!-d/!-f条件及PT标志的重写规则;Nginx需在server块中配置if或try_files规则,确保重写至/index.php?s=$1并传递$query_string,同时开启框架路由。

伪静态规则不写在 ThinkPHP 代码里,而是写在 Web 服务器配置中——Apache 写 .htaccess,Nginx 写 server 块配置。 框架本身只负责解析重写后的 URL(比如 s= 参数或 PATH_INFO),它不参与重写过程。
Apache 下:规则必须写在 .htaccess 文件里,且放对位置
ThinkPHP 5.1.39 默认入口是 public/index.php,所以 .htaccess 必须放在 public/ 目录下(不是项目根目录)。常见错误就是放错位置或文件名写成 htaccess(漏了开头的点)。
-
RewriteEngine On必须开启,否则整段失效 -
RewriteCond %{REQUEST_FILENAME} !-d和!-f缺一不可:只对非真实文件/目录的请求才转发,避免把/static/css/app.css也转给 PHP -
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]中的PT(PassThrough)不能省,否则 Apache 不会把路径部分作为PATH_INFO传给 PHP - 如果项目部署在子目录(如
http://site.com/myapp/),需加RewriteBase /myapp/
Nginx 下:规则必须写进站点的 server 块,不能靠宝塔下拉菜单
小皮、宝塔等面板的「伪静态 → ThinkPHP」选项默认套用 Laravel 规则(try_files $uri $uri/ /index.php?$args),但 TP5.1.39 默认依赖 s= 参数,这个规则根本不会带 s=,导致 $_GET['s'] 为空、路由全 404。
- 正确做法是手动编辑配置,在
location / { }块里写:if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; } -
last不能换成break:前者会重新匹配 location,后者直接终止,后续 PHP 处理块不生效 - 确保
location ~ \.php$块存在,且含fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - 若入口实际是
public/index.php(TP5.1 推荐方式),rewrite 目标要改成/public/index.php?s=$1
框架层必须同步开启路由,否则服务器重写了也没用
服务器把请求转给了 index.php,但 TP5.1.39 默认关闭路由,所有请求都会走普通模式(?s= 解析),而你又没带 s= 参数,结果就是 404 或跳首页。
立即学习“PHP免费学习笔记(深入)”;
- 打开
config/app.php,确认以下三项已设:'url_route_on' => true, 'url_html_suffix' => '', 'pathinfo_depr' => '/'
-
url_html_suffix设为空,才能支持/user/list这种无后缀访问;设成'html'就只能走/user/list.html - 别碰
url_common:TP5.1.39 默认为false(即启用 PATH_INFO),改它反而可能退化到普通模式
最常被忽略的一点:Nginx 配置改完必须执行 nginx -t && nginx -s reload,Apache 要重启服务或确认 AllowOverride FileInfo Options 已生效——规则写得再对,服务没重载等于白干。



















