
本文详解如何通过 .htaccess 正确配置 Apache2,将 /myapi/ 子目录下的所有动态请求(如 /myapi/books)统一路由至 src/index.php,同时排除静态资源,避免重写循环与性能损耗。
本文详解如何通过 `.htaccess` 正确配置 apache2,将 `/myapi/` 子目录下的所有动态请求(如 `/myapi/books`)统一路由至 `src/index.php`,同时排除静态资源,避免重写循环与性能损耗。
在基于 Apache2 的 PHP 项目中(如使用 Slim、Laravel 或自定义路由框架),常需将子目录(如 /var/www/html/myapi/)设为独立 API 入口,并实现「前端控制器模式」——即所有非静态资源的请求均交由单一入口文件(如 src/index.php)处理。这要求 .htaccess 重写规则精准、高效且安全。
以下是一个推荐的、生产就绪的 .htaccess 配置,应放置于 /var/www/html/myapi/.htaccess:
RewriteEngine On # 将所有不匹配静态文件扩展名的请求,重写到 src/index.php RewriteRule !\.(png|jpe?g|gif|zip|css|svg|js|php|woff2?|ttf|eot|ico|xml|txt)$ src/index.php [END]
✅ 关键优化说明:
- ! 前缀 + 扩展名列表:!\.(png|jpe?g|...) 表示“不以这些扩展名结尾”,直接内联于 RewriteRule,无需额外 RewriteCond,提升性能并简化逻辑。
- jpe?g 支持 .jpg 和 .jpeg:正则更健壮;新增 php 排除(防止意外重写 .php 脚本本身)、woff2?/ttf/eot(字体文件)、ico/xml/txt(常见静态资源)。
- 使用 [END] 替代 [L](Apache 2.4+):[END] 彻底终止当前重写流程,防止后续规则(包括父目录或主配置中的规则)再次介入,彻底规避重写循环风险;而 [L] 仅停止当前轮次,仍可能触发新一轮匹配。
- 省略 QSA:因目标路径 src/index.php 不含查询字符串,Apache 默认透传原始 QUERY_STRING,显式添加 QSA 属冗余。
- *无捕获组 `(.)**:原规则(.*) src/index.php` 未使用捕获内容,纯属低效冗余;新规则语义清晰、执行更快。
⚠️ 注意事项:
- 确保 Apache 已启用 mod_rewrite 模块:a2enmod rewrite,并重启服务(systemctl restart apache2)。
- 确保虚拟主机或目录允许 .htaccess 覆盖:对应
块中需包含 AllowOverride All(而非 None)。 - Docker 用户特别注意:如使用容器部署(如问题中提到的 volume mount),请验证 .htaccess 文件是否真实挂载到容器内路径 /var/www/html/myapi/.htaccess,且权限可读(chmod 644)。文件缺失或挂载错误是“规则不生效”的最常见原因。
- 若运行于 Apache 2.2(旧版),[END] 不可用,请降级为 [L],但务必确保无其他冲突规则;同时建议升级至 2.4+ 以获得更安全的重写语义。
✅ 验证方式:
访问 http://localhost/myapi/books?filter=active,应在 src/index.php 中通过 $_SERVER['REQUEST_URI'] 获取原始路径 /myapi/books(而非重写后路径),并通过 $_GET['filter'] 正确获取查询参数,证明路由与参数透传均工作正常。
该配置兼顾安全性、性能与可维护性,是现代 PHP 子目录应用的标准实践。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











