偽靜態規則
程式只有 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然後隨便點開一個商品頁面,能正常開啟就說明偽靜態生效了。
