伪静态规则
程序只有 index.php 一个入口,所有页面都靠它路由。不配伪静态,除了首页什么都打不开。
Docker 安装不需要配,镜像里已经写好了。
下面三份规则语义完全一致:既做伪静态转发,也顺手把不该被访问的文件挡在外面(日志、数据库备份、配置、
.env、composer.json等)。建议整段复制,不要只抄最后那条location /。
Nginx
宝塔用户:网站 → 点站点 → 伪静态,整段粘进去保存。
# 只放行唯一入口 index.php,其余 .php 一律不执行
if ($uri ~* "^/(?!index\.php(/|$)).*\.php(/|$)") { return 404; }
location ~* ^/(runtime|kernel|config|vendor)/ { return 404; }
location ~ /\.(?!well-known) { return 404; }
location ~* \.(log|sql|sqlite|db|db-wal|db-shm|bak|old|save|orig|swp|swo|tmp|ini|lock)$ { return 404; }
location ~* (~|composer\.(json|lock)|package(-lock)?\.json)$ { return 404; }
location / {
try_files $uri $uri/ /index.php?s=$uri&$args;
}第一条 if 为什么不写成 location:宝塔的配置模板里,PHP 的 include enable-php-XX.conf 排在伪静态之前,而 nginx 的正则 location 是按出现顺序匹配、首个命中即止 —— 写成 location ~ \.php$ 永远轮不到它执行,会静默失效。if 跑在更早的 rewrite 阶段,不受顺序影响。
Apache
不用配。 程序根目录的 .htaccess 已经写好了,确认它没被上传工具漏掉即可。
只要确认 Apache 开了 mod_rewrite,并且站点配置里 AllowOverride 不是 None。
IIS
Windows + IIS 需要装 URL Rewrite 2.0 模块,然后把下面这段放进站点根目录的 web.config(宝塔 Windows 版直接粘到伪静态框里):
<rules>
<!-- ① 程序目录 -->
<rule name="acg_deny_dir" stopProcessing="true">
<match url="^(runtime|kernel|config|vendor)(/|$)"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ② 点文件 / 点目录(放行 ACME 证书校验) -->
<rule name="acg_deny_dotfile" stopProcessing="true">
<match url="(^|/)\.(?!well-known)"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ③ 敏感后缀 -->
<rule name="acg_deny_ext" stopProcessing="true">
<match url="\.(log|sql|sqlite|db|db-wal|db-shm|bak|old|save|orig|swp|swo|tmp|ini|lock)$"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ④ 备份副本与依赖清单 -->
<rule name="acg_deny_file" stopProcessing="true">
<match url="(~|composer\.(json|lock)|package(-lock)?\.json)$"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ⑤ 只放行唯一入口 index.php -->
<rule name="acg_deny_php" stopProcessing="true">
<match url="^(?!index\.php(/|$)).*\.php(/|$)"/>
<action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="Not Found" statusDescription="Not Found"/>
</rule>
<!-- ⑥ 伪静态 -->
<rule name="acg_rewrite" stopProcessing="true">
<match url="^(.*)$"/>
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="index.php?s={R:1}" appendQueryString="true"/>
</rule>
</rules>用的是 URL Rewrite 1.x 的话不支持
CustomResponse,把它换成<action type="AbortRequest"/>,代价是响应体为空。不要改用
requestFiltering的hiddenSegments。 它是任意层级匹配的,会把/admin/config/...后台配置页和插件自带的assets/vendor/、assets/.../config/静态资源一起 404 掉。
站点根目录下放了别的 PHP 程序?
上面三份规则都只放行 index.php 一个入口。如果你在网站根目录里还放了 phpMyAdmin、adminer 之类的 PHP 工具,它们会被一起挡掉 —— 把这类工具挪到独立站点即可。
验证配好没有
访问下面几个地址,都应该是 404:
你的域名/composer.json
你的域名/runtime.log
你的域名/config/database.php然后随便点开一个商品页面,能正常打开就说明伪静态生效了。
