PHP伪静态实际由Web服务器实现,Apache用.htaccess配合mod_rewrite,Nginx用location+try_files;PHP端须通过$_SERVER['REQUEST_URI']安全解析路径,并注意配置衔接点。

PHP 本身不处理 URL 重写,真正起作用的是 Web 服务器(如 Apache 或 Nginx)。所谓“PHP 伪静态”,其实是服务器把看起来像静态路径的请求,转发给 PHP 脚本统一处理。直接在 PHP 里写 $_GET 解析或用 parse_url() 拆路径,解决不了路由分发问题——那只是后续逻辑。
Apache 下用 .htaccess 实现重写(最常见场景)
绝大多数共享主机或本地开发环境用 Apache + .htaccess。核心是启用 mod_rewrite 并写好规则:
- 确认
AllowOverride All已在虚拟主机配置中开启,否则.htaccess不生效 -
RewriteEngine On必须放在规则最前面,漏掉就整个失效 - 常用规则示例(把
/article/123映射到index.php?route=article&id=123):RewriteCond %{REQUEST_FILENAME} !-f<br>RewriteCond %{REQUEST_FILENAME} !-d<br>RewriteRule ^(.*)$ index.php?route=$1 [QSA,L] -
QSA保留原始查询参数,L表示终止后续规则,漏掉L可能导致意外重写循环 - 如果站点不在根目录(比如在
/myapp/),必须加RewriteBase /myapp/,否则重写路径会错位
Nginx 配置 location + fastcgi_param(无 .htaccess)
Nginx 不支持分布式配置文件,所有重写必须写在 server 块里。它没有 .htaccess 的概念,出错时不会静默忽略,而是直接 404 或 500。
- 关键配置段:
location / {<br> try_files $uri $uri/ /index.php?$query_string;<br>} -
try_files是核心:先尝试找真实文件,找不到就 fallback 到index.php,并透传原始查询字符串 - 必须确保
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;正确,否则 PHP 接收到的脚本路径为空,报No input file specified - 如果用了子目录部署(如
/blog/),location要写成location /blog/,且try_files中的 fallback 路径也要对应为/blog/index.php
PHP 端如何安全解析重写后的 URL
服务器把请求转给 PHP 后,$_SERVER['REQUEST_URI'] 是唯一可靠来源。别依赖 $_GET 原始值——它已被重写规则干扰过。
立即学习“PHP免费学习笔记(深入)”;
- 用
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)提取路径部分,再用trim($path, '/')去首尾斜杠 - 避免直接
explode('/', $_SERVER['REQUEST_URI']):URL 可能含查询参数、编码字符(如%20),parse_url更健壮 - 对路径段做白名单校验,比如
in_array($segments[0], ['user', 'post', 'api']),防止恶意路径穿透 - 如果框架用
$_SERVER['PATH_INFO'],注意 Apache 需开启AcceptPathInfo On,Nginx 默认不设该变量,得手动传:fastcgi_param PATH_INFO $fastcgi_path_info;
重写的本质是请求入口的转移,不是 URL 格式美化。最容易被忽略的是服务器配置与 PHP 解析的衔接点:比如 Apache 规则里没加 [QSA],但 PHP 又去拼接 $_SERVER['QUERY_STRING'],结果参数丢失;或者 Nginx 的 try_files 写成 /index.php 却忘了改 SCRIPT_FILENAME,导致空白页。这些地方一错,调试时根本看不到错误提示,只显示 404 或 500。



















