在PHP项目部署过程中,当项目被放置在服务器的子目录下时,默认访问路径会带上子目录名称,这既不美观也不利于后续的路由管理。通过前端控制器配合URL重写技术,可以让子目录下的项目拥有类似根目录的访问体验,用户无需感知子目录的存在。

核心实现原理
整个实现过程主要依赖两个核心部分:
- 前端控制器:作为所有请求的入口,统一接收用户请求,再根据路由规则分发到对应的业务处理逻辑。
- URL重写:服务器层面的规则,将用户访问的伪静态URL映射到实际的前端控制器文件,隐藏子目录和真实的文件结构。
前端控制器编写
前端控制器通常是一个入口文件,比如index.php,放在项目的子目录根下,负责解析请求路径并加载对应的业务代码。以下是一个简单的前端控制器示例:
<?php
// 定义项目根目录常量,避免路径混乱
define('APP_PATH', __DIR__ . '/');
// 获取请求的路径,去掉开头的斜杠和子目录前缀
$requestUri = $_SERVER['REQUEST_URI'];
// 假设项目部署在子目录 /myapp 下,这里替换为实际的子目录名称
$subDir = '/myapp';
$path = str_replace($subDir, '', $requestUri);
$path = trim($path, '/');
// 简单的路由匹配逻辑
$routes = [
'' => 'home.php',
'user/list' => 'user/list.php',
'article/detail' => 'article/detail.php',
];
// 如果路径在路由中,加载对应文件,否则返回404
if (isset($routes[$path])) {
require APP_PATH . $routes[$path];
} else {
header("HTTP/1.0 404 Not Found");
echo '页面不存在';
}
URL重写规则配置
URL重写需要依赖服务器环境,不同的服务器配置方式不同,下面分别介绍Apache和Nginx的配置方法。
Apache服务器配置
Apache需要开启mod_rewrite模块,然后在项目的子目录下创建.htaccess文件,添加以下规则:
# 开启重写引擎
RewriteEngine On
# 如果请求的不是真实存在的文件或目录,才转发到前端控制器
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 假设项目在子目录 /myapp 下,将请求转发到该目录的 index.php
RewriteRule ^(.*)$ /myapp/index.php [QSA,L]
Nginx服务器配置
Nginx的配置需要在对应的server块中添加如下规则:
location /myapp {
# 子目录的实际路径,替换为你的项目路径
root /var/www/html;
index index.php;
# 如果请求的文件或目录不存在,转发到子目录下的 index.php
if (!-e $request_filename) {
rewrite ^/myapp/(.*)$ /myapp/index.php last;
}
# PHP解析配置
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;
}
}
常见问题排查
- 如果重写规则不生效,首先检查服务器是否开启了对应的重写模块,Apache查看
mod_rewrite是否加载,Nginx检查配置是否有语法错误。 - 子目录名称替换错误会导致路由匹配失败,需要确认前端控制器和重写规则中的子目录名称完全一致。
- 静态资源访问异常时,需要确保静态资源的路径没有被重写规则错误转发,可以在重写规则中排除静态资源后缀的匹配。
总结
通过前端控制器统一入口,结合服务器的URL重写规则,就可以轻松实现PHP子目录的伪根目录访问效果,既简化了用户的访问路径,也让项目的路由管理更加灵活。实际开发中可以根据项目的路由复杂度,扩展前端控制器的路由匹配逻辑,适配更多的业务场景。