本文详解如何配置 apache 的 `.htaccess` 文件,使 `/css/main.css` 等静态资源请求自动映射到 `public/css/main.css`,同时确保 mvc 路由不冲突、无重定向循环。
在基于 MVC 架构的 PHP 应用中,将 Web 可访问文件(如 CSS、JS、图片)统一置于 public/ 目录是常见且安全的做法。但若希望前端 HTML 中直接使用 而非 ,就必须借助 .htaccess 实现「透明路径重写」——即浏览器请求 /css/main.css 时,服务器内部将其指向 public/css/main.css
,而 URL 地址栏保持不变。
关键挑战在于:避免重写规则间的冲突与无限重定向循环。原始配置中 RedirectMatch 与后续 RewriteRule 未做前置拦截,导致对已重写为 public/xxx 的请求再次匹配、反复重写,最终触发 500 错误或浏览器重定向失败。
以下是经过生产验证的、结构清晰且具备防御性的 .htaccess 配置(适配子目录部署场景,如 /BU/cs-602/developer-story/):
RewriteEngine On RewriteBase /BU/cs-602/developer-story/ # 1. 首页请求:/ 或 /index.* → public/index.php(终止) RewriteRule ^(\/||.*index\..*)$ public/index.php [L,QSA] # 2. 安全短路:若请求路径已含 "public/",直接放行(防止循环) RewriteRule ^(.*public\/.*)$ $1 [L,QSA] # 3. 静态资源识别:匹配非 PHP/HTML/HTM 的扩展名(如 .css, .js, .png) RewriteCond %{REQUEST_URI} \.(?!php|htm|html)[a-zA-Z0-9]+$ [NC] # → 重写为 public/ + 原路径,并终止(L) RewriteRule ^(.*)$ public/$1 [L,QSA] # 4. MVC 路由兜底:仅当请求路径不是真实文件/目录/符号链接时,交由 index.php 处理 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^([\w\d\s\-\_\/\%]*)$ public/index.php?p=$1 [L,QSA]
✅ 核心设计逻辑说明:
⚠️ 注意事项:
该方案已在本地开发环境(XAMPP/MAMP)及 Linux 服务器实测通过,兼顾安全性、可维护性与 MVC 架构规范,是子目录部署型 PHP 应用的标准实践之一。