ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

tpshop 3二级页面404修复:Linux下Nginx/Apache伪静态配置指南

tpshop 3二级页面404修复:Linux下Nginx/Apache伪静态配置指南 上周帮朋友处理一台Linux服务器上的tpshop 3部署问题界面装好后首页展示一切正常商品分类一点进去就是404白底黑字的Nginx错误页直接怼在脸上。装过tpshop的朋友应该都有印象这种“二级页面404”在Linux环境里极其典型要么是伪静态规则没挂上要么是挂了但参数不对。好在问题本身不算复杂排查方向对了几分钟就能修完。这篇文章我就把这套完整的排查思路和修复方式写下来从tpshop 3的URL机制讲起到Nginx和Apache两种环境的实际配置再补上我踩过的坑和验证技巧。适合刚把tpshop 3装到Linux上、二级页面全部404的新手也适合帮人排查但觉得原理没捋清的运维朋友。1. 先搞清楚tpshop的URL机制再动手改配置很多人拿到404就急着百度规则、复制粘贴结果改完还是打不开越改越乱。我建议先花5分钟弄懂tpshop 3在服务器上是怎么处理URL的知道原理之后几乎所有404都逃不出那一两个原因。1.1 tpshop 3的URL结构长什么样tpshop 3是基于ThinkPHP 3.x开发的开源商城系统默认使用REWRITE模式。也就是说前台页面的URL不是传统的xxx.php?mHomecGoodsaindex这种带问号的参数形式而是类似这样的路径http://你的域名/Home/Goods/goodsInfo/id/100.html拆开看Home是模块名Goods是控制器goodsInfo是方法名id/100是参数。整串路径在服务器磁盘上并不对应任何真实目录和文件它只是一个“虚拟路径”靠服务器把请求转交给入口文件index.php去解析。所以二级页面指的是除首页之外的商品列表、商品详情、文章页、购物车这些页面它们走的基本都是上面这种伪静态路径。首页之所以不404是因为访问/或者/index.php时服务器能直接定位到物理文件index.php不需要额外的重写逻辑。1.2 404为什么总在二级页面先冒出来了解了URL结构之后404的真正原因就清楚了浏览器请求的是一个磁盘上不存在的路径而服务器又不知道该把这个请求交给谁处理于是直接返回“文件不存在”的404。这跟tpshop程序本身没太大关系PHP代码没坏、数据库没坏、配置文件也没坏问题出在“网络服务器层”。打个比方整个tpshop的运行过程就像一栋办公楼index.php是前台二级页面是各个办公室。访客进大门时首页保安能直接看到前台位置所以顺利进入。但访客点名要找某个具体办公室时二级页面保安手里如果没有一张“带路指示图”伪静态规则就只会说“查无此地”把人拦在门外——这就是404。反过来说这个现象也给了我们一个很有用的判断依据只要首页能正常打开、二级页面都404基本可以确定PHP环境和数据库没有问题直接去查服务器重写规则就行不用在代码层面反复折腾。1.3 修复方案的核心思路伪静态规则伪静态规则的核心任务就是把“磁盘上不存在的路径”改写成“入口文件能识别的URL参数”再交给index.php去处理。Nginx和Apache的写法虽然不一样但思路完全一致接收请求的URI检查这个路径对应的文件或目录是否真实存在如果不存在就重写成index.php?s/Home/Goods/goodsInfo/id/100.html这样的格式index.php根据s参数解析出模块、控制器、方法然后正常输出页面。重点在这里ThinkPHP 3.x 依赖s参数来识别重写后的路径规则里如果少了s或者格式不对即使重写生效了页面也一样打不开甚至会出现ThinkPHP的“页面不存在”提示。我见过太多人在网上复制了一段规则没注意参数格式粘上去之后还是404问题就出在这个细节上。2. 动手前的环境核对LNMP/LAMP下容易忽略的细节规则不是随便贴一段就能用的服务器环境不同生效方式和前提条件也不同。我在改规则之前一般先花几分钟确认环境和模块状态免得改完之后发现连Rewrite模块都没加载白白浪费时间。2.1 tpshop 3对Linux运行环境的基本要求tpshop 3是典型的LNMP/LAMP架构应用部署环境建议满足以下版本要求这些我都实测过组件推荐版本备注PHP5.6 - 7.1老框架PHP 8以上容易出兼容问题MySQL5.5 - 5.78.0较新部分函数和连接方式可能不兼容Nginx1.10LNMP环境最常用Apache2.4宝塔面板也常见扩展pdo_mysql、curl、gd、openssl、fileinfo缺少扩展会导致安装完成但功能异常特别提醒一下很多人装tpshop 3时图新鲜用了PHP 7.4甚至8.0结果装完后虽然首页能开但商品页频繁报错。这属于版本兼容性问题不在本文404讨论范围内但如果遇到“二级页面不是404而是报错页”的情况先回退PHP版本试一下。404的排查重点仍然是重写规则。2.2 Apache和Nginx两种环境配置差异一览Nginx和Apache处理伪静态的方式差别很大我先把关键差异列出来后面实操部分再展开对比项NginxApache规则存放位置站点conf文件的server块内.htaccess文件或httpd配置生效方式修改后reload nginx需要开AllowOverride mod_rewrite判断文件不存在if (!-e $request_filename)RewriteCond %{REQUEST_FILENAME} !-f等典型规则rewrite ^/(.*)$ /index.php?s$1 last;RewriteRule ^(.*)$ index.php?s/$1 [QSA,PT,L]常见坑忘记nginx -t、include路径不对AllowOverride None导致htaccess失效判断服务器用的是哪个最简单的方式是看首页是Nginx风格还是Apache风格或者直接执行ps aux | grep -E nginx|apache|httpd。知道自己用的是哪种环境再决定看哪一节。2.3 PHP-FPM和pathinfo的关系Nginx环境还有一个容易忽略的点Nginx自身不执行PHP它把PHP请求通过FastCGI交给PHP-FPM处理。这个过程里SCRIPT_FILENAME和cgi.fix_pathinfo这两个参数有一点不对劲就可能出现“nginx已经重写正确但PHP拿到的脚本路径不对”结果同样表现为404。在PHP配置文件php.ini里有个参数叫cgi.fix_pathinfo旧版本默认可能是1新版PHP默认是0。对于thinkPHP 3.x走rewrite s参数的方案来说理论上不依赖pathinfo但如果你的tpshop配置了PATHINFO模式的URLcgi.fix_pathinfo0可能导致PHP解析不到控制器出现404或者“控制器不存在”的错误。我用个快递类比你就明白了Nginx是快递驿站PHP-FPM是收件人SCRIPT_FILENAME就是收件地址。地址写错了驿站按规则把件往正确的方向送但收件人根本收不到最后还是算投递失败。所以配置完rewrite规则后顺手看一眼Nginx的fastcgi配置里有没有fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;这一行。3. 实操完整修复二级页面404环境核对完下面直接上操作。我按Nginx和Apache两条线分别写每一步都给出可直接复制的配置和验证命令。你在操作时先确认自己的环境然后照着对应的那部分来。3.1 Nginx环境下的伪静态规则配置步骤Nginx环境里tpshop 3的404绝大多数是站点配置文件里缺少rewrite规则。下面按步骤来第一步找到Nginx站点配置文件手工部署的通常在这些位置/etc/nginx/conf.d/ /etc/nginx/sites-available/ /usr/local/nginx/conf/vhost/如果用的是宝塔面板配置文件在/www/server/panel/vhost/nginx/你的域名.conf第二步在server块内加入rewrite规则打开配置文件找到server { }块把下面这段加进去server { listen 80; server_name yourdomain.com; root /var/www/html; index index.php index.html; location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?s$1 last; } } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }这段规则的关键在if (!-e $request_filename)意思是“如果请求的文件或目录不存在”。图片、CSS、JS这些真实存在的静态文件不会被重写正常访问只有虚拟的伪静态路径才会被转给index.php。第三步验证配置并重载Nginx改完配置文件先执行语法检查再reloadnginx -t nginx -s reload或者用systemctlsystemctl reload nginx第四步验证二级页面先登录tpshop后台复制某一个分类的URL然后浏览器访问。如果还是404再看下一步。补充一个常见场景tpshop 3如果安装在子目录比如放在/var/www/html/tpshop并且通过http://域名/tpshop访问那rewrite规则里的路径也要对应调整location /tpshop/ { if (!-e $request_filename) { rewrite ^/tpshop/(.*)$ /tpshop/index.php?s$1 last; } }但说实话我建议在子目录部署时直接在tpshop目录内单独建站点配置成独立域名访问这样可以少改很多地方避免后续各种路径问题。3.2 Apache环境下的Rewrite配置步骤Apache环境下二级页面404一般是两种情况一是mod_rewrite模块没启用二是AllowOverride没设置成All导致.htaccess文件里的规则根本不生效。第一步启用Rewrite模块Debian/Ubuntu系a2enmod rewrite systemctl restart apache2CentOS/RHEL系使用Apache 2.4默认安装时mod_rewrite通常已编译进核心确认一下httpd -M | grep rewrite如果有rewrite_module输出说明模块已加载。第二步修改虚拟主机配置打开AllowOverride打开Apache的虚拟主机配置文件把AllowOverride None改成AllowOverride AllDirectory /var/www/html Options Indexes FollowSymLinks AllowOverride All Require all granted /Directory如果不改这一步tpshop根目录下的.htaccess规则会被直接忽略那你写什么都白搭。第三步确认.htaccess文件存在且内容正确进入tpshop安装根目录确认有没有.htaccess。没有的话就创建cd /var/www/html vim .htaccess写入以下内容IfModule mod_rewrite.c Options FollowSymlinks -Multiviews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?s/$1 [QSA,PT,L] /IfModule这段规则的含义和Nginx版本一致只有请求的路径既不是真实目录!-d也不是真实文件!-f时才重写到index.php?s/$1。第四步重启Apachesystemctl restart apache2 # 或者 systemctl restart httpd重启之后访问二级页面测试。如果配置正常不会再是Apache 404页面。3.3 配置完成后的验证与缓存清理规则配置好了页面有时还是404原因多半是ThinkPHP的Runtime缓存没清。tpshop 3会把路由解析结果缓存到Application/Runtime目录规则改动前后旧的缓存数据会干扰新的URL解析。清理方法cd /var/www/html rm -rf Application/Runtime/*如果删除时提示权限不足是因为Runtime目录需要PHP进程www用户有写权限chown -R www:www Application/Runtime # 或 chmod -R 755 Application/Runtime清完缓存用命令行验证URL返回码更直观curl -I http://yourdomain.com/Home/Goods/goodsInfo/id/1.html返回HTTP/1.1 200 OK说明修复成功。如果还是404继续看下一节的排查清单。4. 常见问题与排查技巧实录这一节汇总我在实际部署中遇到的高频问题和处理思路。有些问题表面上也叫“二级页面404”但根源各有不同我按症状分类整理成速查表和经验记录。4.1 二级页面404问题速查表症状可能原因处理方法所有二级页面404首页正常Nginx里没有rewrite规则在server块添加location规则并reload带.html的二级页面全是404规则存在但位置放错或include没生效确认规则在对应server块内nginx -t页面显示ThinkPHP“页面不存在”rewrite规则生效但s参数格式不对检查规则是index.php?s$1注意s和后缀Apache环境下.htaccess完全无效AllowOverride为None或mod_rewrite未加载将AllowOverride改为Alla2enmod rewrite首页和部分页面可以打开部分404Runtime缓存旧路由数据删除Application/Runtime下缓存并清浏览器缓存修改配置后Nginx启动失败语法错误、缺少大括号、路径写错执行nginx -t逐个排查错误行伪静态URL打开后变成502 Bad GatewayPHP-FPM未启动或版本切换后sock路径变了确认php-fpm运行状态检查fastcgi_pass配置Linux本地能打开外网访问404云服务器安全组或防火墙拦截检查80/443端口出入站规则所有页面404且图片CSS都打不开站点root目录设置错误确认root指向tpshop源码根目录安装后直接白屏没有任何错误PHP版本过高或缺少扩展用PHP 5.6/7.1环境启用pdo_mysql等扩展表格里有一半情况我在不同客户机器上都见过其中最隐蔽的是“ThinkPHP页面不存在”——它看起来和普通404不一样但从用户体验来说都是打不开页面。遇到这种核心思路就是检查规则里的s参数格式以及清理Runtime缓存。4.2 我踩过的几个坑和排查思路这里分享三个我印象比较深的实际案例每一个都浪费了不少时间写出来帮大家避开。坑一复制了网上通用ThinkPHP规则但少了s参数有一次在Nginx里贴了一段网上流行的通用TP规则只写了rewrite ^/(.*)$ /index.php last;没有带s$1。结果所有二级页面全部变成ThinkPHP“页面不存在”。原因是ThinkPHP 3.x在REWRITE模式下必须通过s参数接收重写后的路径没有s入口文件不知道要去解析哪个模块。那次之后我对复制规则这件事就特别敏感——哪怕规则来源再权威也要先看懂参数的用途。std电子书库坑二SELinux开启导致PHP-FPM读不到文件一台CentOS 7机器上Nginx配置、伪静态规则全部检查过一遍首页能开、二级页面404但错误日志里反复出现权限相关报错。最后发现是SELinux处于Enforcing状态导致PHP-FPM进程尽管有文件权限却被系统安全策略拦住了。快速验证方法getenforce如果是Enforcing先临时放行测试setenforce 0如果页面恢复正常说明就是SELinux的问题。这种场景下不建议直接永久关闭SELinux生产环境也不该这么干而是针对web目录做上下文修正restorecon -Rv /var/www/html或者用chcon设置正确的httpd_sys_content_t上下文。这个问题在纯Linux环境下很典型Windows里不会遇到所以容易让习惯了Windows部署的人摸不着头脑。坑三宝塔面板切换PHP版本后伪静态规则被新站点覆盖用宝塔装tpshop的时候操作系统选了PHP 7.1后来又切到PHP 7.4测试兼容性。结果网站配置里自动生成了一段新的伪静态规则覆盖了之前手动粘贴的tpshop规则。二级页面又变成404而且宝塔面板里看起来一切正常。解决办法是在站点设置里重新选择“伪静态”粘贴tpshop对应规则然后重载Nginx和PHP-FPM。经验之谈切完PHP版本顺手检查一遍站点配置里的伪静态别想当然以为不会变。4.3 几个容易忽略的细节有些细节不影响首页但会影响二级页面真实表现这里统一列一下浏览器缓存配置改完后用普通浏览器访问经常还是旧的404页按CtrlF5强制刷新或开无痕窗口测试能省很多不必要的误判。URL模式配置tpshop 3的配置文件在Application/Common/Conf/config.php或数据库字典里URL_MODEL要设为2REWRITE并且URL_HTML_SUFFIX要包含.html。如果这两项被改过和伪静态规则不匹配可能出现带后缀404、不带后缀能开的情况。根目录设置站点root如果指到了没有index.php的目录访问首页会变成403或目录列表二级页面则全部404。确认root路径直接指向tpshop源码目录而不是外层包了一层。错误日志不管问题多难查先看日志。Nginx错误日志通常在/var/log/nginx/error.logPHP-FPM日志在/var/log/php-fpm.log或宝塔面板的“日志”标签页里。日志一行往往直接指出瓶颈比盲目排查快得多。防火墙和安全组Linux服务器如果开了firewalld或者云服务商安全组没放行60端口外网访问就会出现“能ping通但页面404/超时”的神奇表现。这个和伪静态无关但症状容易混淆遇到就顺手查一下。最后分享一个实用小技巧在处理这套tpshop 3 404问题的时候我个人养成了一个习惯先通过curl访问http://域名/index.php/Home/Goods/goodsInfo/id/1.html。如果带index.php的路径能正常打开那就非常确定程序本身和PHP运行环境没问题问题100%出在伪静态重写这一层。如果带index.php都打不开那就先检查PHP-FPM、MySQL连接和PHP版本兼容性别一开始就扎进伪静态规则里。按照这个思路排查几乎每次都能在几分钟内定位到问题所在。tpshop 3虽然是一套有点年头的商城系统但部署到Linux上只要把URL重写这层原理弄明白绝大部分404问题都不再是什么难事。希望这篇记录能帮你少走一些弯路。
返回列表