下面我将分步详细讲解如何在不同的服务器环境下设置 PHP 伪静态。

核心概念:URL 重写
伪静态的核心技术是 URL 重写,当服务器收到一个请求时,它会检查一个特殊的规则文件(如 .htaccess 或 nginx.conf),如果请求的 URL 与规则匹配,服务器会“在幕后”将 URL 重写为另一个实际的 URL,然后处理这个新的 URL,最后将结果返回给用户,整个过程对用户是透明的。
Apache 服务器设置
Apache 是最常使用伪静态的服务器之一,设置非常简单,主要依赖 mod_rewrite 模块和 .htaccess 文件。
步骤 1:确保 mod_rewrite 模块已启用
大多数虚拟主机服务商已经默认开启了此模块,你可以通过创建一个 phpinfo.php 文件,内容为 <?php phpinfo(); ?>,然后在浏览器中访问,搜索 mod_rewrite,Loaded Module 列表中有它,说明已启用。
如果没有启用,你需要编辑 Apache 的主配置文件 httpd.conf(或 apache2.conf),找到以下行并取消注释:

LoadModule rewrite_module modules/mod_rewrite.so
然后重启 Apache 服务。
步骤 2:创建或编辑 .htaccess 文件
在你的网站根目录(或需要伪静态的目录)下,创建一个名为 .htaccess 的文件,这个文件可以控制当前目录及其子目录的 URL 重写规则。
重要提示:
- 确保你的 Apache 配置中允许使用
.htaccess文件,通常在httpd.conf中会有类似这样的配置:<Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride All <!-- 确保这里是 All --> Require all granted </Directory> .htaccess文件是隐藏文件,在 Linux/Mac 上创建时可能需要使用touch .htaccess命令,或者在 FTP/SFTP 客户端中设置“显示隐藏文件”。
步骤 3:编写重写规则
在 .htaccess 文件中,你需要使用 RewriteEngine 和 RewriteRule 指令。

示例 1:将 product.php?id=123 重写为 product/123
这是最经典的伪静态案例。
# 开启重写引擎 RewriteEngine On # 设置重写的基准目录,如果规则不匹配,会跳过 # 通常可以省略,但写上更规范 RewriteBase / # RewriteRule 规则 # 格式: RewriteRule 模板 替代标志 [选项] # 模式: ^product/([0-9]+)$ 匹配以 "product/" 开头,后面跟着一个或多个数字的 URL # 替代: product.php?id=$1 将匹配到的部分(用括号捕获)作为 $1,替换为 product.php?id=$1 # 选项: L Last,表示如果此规则匹配,则停止处理后续规则 RewriteRule ^product/([0-9]+)$ product.php?id=$1 [L]
示例 2:将 article.php?cat=news&id=456 重写为 article/news/456
RewriteEngine On RewriteBase / RewriteRule ^article/([a-z]+)/([0-9]+)$ article.php?cat=$1&id=$2 [L]
示例 3:将 user.php?username=john 重写为 user/john
RewriteEngine On RewriteBase / RewriteRule ^user/([a-zA-Z0-9_-]+)$ user.php?username=$1 [L]
示例 4:将所有对 .html 结尾的请求都重写到 index.php
这种方式常用于单页应用或框架。
RewriteEngine On
RewriteBase /
# 如果请求的文件或目录真实存在,则不重写
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 将所有其他请求都重写到 index.php
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
# QSA (Query String Append) 表示保留原有的查询字符串
# 访问 /about.html?page=2 会被重写为 index.php?url=about.html&page=2
Nginx 服务器设置
Nginx 的处理方式与 Apache 不同,它不使用 .htaccess 文件,所有的重写规则都需要在 Nginx 的配置文件中定义,通常是 nginx.conf 或你网站的配置文件(位于 /etc/nginx/sites-available/ 目录下)。
步骤 1:编辑 Nginx 配置文件
使用 sudo nano 或 vim 打开你的网站配置文件。
步骤 2:在 server 块中添加 location 规则
你需要将伪静态规则添加到 server 块内。
示例 1:将 product.php?id=123 重写为 product/123
server {
listen 80;
server_name your_domain.com;
root /var/www/html;
index index.php index.html index.htm;
# ... 其他配置 ...
# 将 /product/123 这样的请求转发给 product.php
location /product {
# try_files 会按顺序检查文件是否存在
# $uri 是请求的 URI,/product/123
# $uri 对应的文件不存在,则将请求转发给后面的 @rewrite 规则
try_files $uri $uri/ @rewrite;
}
# 定义一个重写命名的 location
location @rewrite {
# 将请求重写到后端的 PHP 脚本
# $request_uri 是完整的原始请求 URI,/product/123
# last 表示停止处理当前层级的 rewrite 规则,并搜索匹配的 location
rewrite ^/product/([0-9]+)$ /product.php?id=$1 last;
}
# ... PHP 处理部分 ...
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock; # 注意这里的路径和版本号
}
}
示例 2:将所有请求重写到 index.php(框架常用)
server {
listen 80;
server_name your_domain.com;
root /var/www/html;
index index.php;
# 如果请求的不是真实文件或目录,则重写
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# ... PHP 处理部分 ...
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
步骤 3:测试并重载 Nginx 配置
修改完配置文件后,不要立即重启,先测试配置是否正确:
sudo nginx -t
如果显示 syntax is ok 和 test is successful,则重载 Nginx 使配置生效:
sudo systemctl reload nginx
PHP 代码中如何获取伪静态后的参数?
当 URL 被重写后(如 product/123),PHP 脚本本身并不知道这个变化,你需要从 $_SERVER 超全局变量中解析出原始 URL 的信息。
以 Apache 的 RewriteRule ^product/([0-9]+)$ product.php?id=$1 [L] 为例:
当用户访问 http://example.com/product/123 时,服务器会内部请求 http://example.com/product.php?id=123,在你的 product.php 文件中,你可以直接通过 $_GET['id'] 来获取值。
product.php 文件内容:
<?php
// 当访问 /product/123 时,$_GET['id'] 的值就是 123
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$productId = $_GET['id'];
echo "您正在查看产品 ID: " . htmlspecialchars($productId);
// 这里可以连接数据库查询产品信息
} else {
echo "无效的产品 ID。";
}
?>
对于更复杂的 URL(如 article/news/456):
假设 Nginx 规则是 rewrite ^/article/([a-z]+)/([0-9]+)$ /article.php?cat=$1&id=$2 last;
在 article.php 中,你可以这样获取:
<?php $category = $_GET['cat'] ?? 'default'; // 使用 ?? 提供默认值 $articleId = $_GET['id'] ?? 0; echo "分类: " . htmlspecialchars($category) . "<br>"; echo "文章 ID: " . htmlspecialchars($articleId); ?>
常见问题与注意事项
-
404 Not Found 错误:
- Apache:检查
.htaccess语法是否正确,确保AllowOverride All已设置。 - Nginx:检查
location和rewrite规则是否正确,并确保已重载配置。 - 通用:检查重写后的目标文件(如
product.php)是否真实存在于服务器的正确路径。
- Apache:检查
-
500 Internal Server Error 错误:
- 通常是
.htaccess或 Nginx 配置文件有语法错误,仔细检查拼写、括号匹配等。
- 通常是
-
循环重定向:
- 当一个 URL 被重写后,又匹配了另一条规则,最终可能又回到原始 URL,形成死循环,检查你的
RewriteRule和RewriteCond,确保逻辑清晰,并用[L]标记来终止规则链。
- 当一个 URL 被重写后,又匹配了另一条规则,最终可能又回到原始 URL,形成死循环,检查你的
-
性能考虑:
URL 重写会增加一点点服务器 CPU 的负担,但对于现代服务器来说,这点开销可以忽略不计,清晰的规则和合理的缓存策略更重要。
-
开发环境 vs. 生产环境:
- 在本地开发环境(如 XAMPP, MAMP, WAMP)中,确保 Apache 的
httpd.conf中LoadModule rewrite_module和AllowOverride All都已正确配置。
- 在本地开发环境(如 XAMPP, MAMP, WAMP)中,确保 Apache 的
| 步骤 | Apache | Nginx |
|---|---|---|
| 检查模块/配置 | 确保 mod_rewrite 已启用,AllowOverride All 已设置。 |
直接在配置文件 (server 块) 中编写规则。 |
| 配置文件 | 在网站根目录创建/编辑 .htaccess 文件。 |
编辑 /etc/nginx/sites-available/ 下的网站配置文件。 |
| 编写规则 | 使用 RewriteEngine On 和 RewriteRule。 |
使用 location 和 rewrite 指令。 |
| 应用配置 | 无需重启,.htaccess 修改后自动生效(但 Apache 需要读取权限)。 |
修改后必须运行 sudo nginx -t 测试,sudo systemctl reload nginx。 |
| PHP 获取参数 | 直接通过 $_GET 获取重写后传递的参数。 |
直接通过 $_GET 获取重写后传递的参数。 |
理解了 URL 重写的原理,并根据你的服务器类型选择正确的配置方法,你就可以轻松地为你的 PHP 项目设置伪静态了。
