phpenv默认用nginx,强制跳转www需在server块顶层用return 301配置独立server块处理非www请求,避免被自动覆盖;php中http_host为跳转后域名,不应再做php层跳转。

phpEnv 默认用的是 Nginx,不是 Apache,所以不能直接套用 .htaccess 规则;强制跳转 www 必须在 Nginx 配置里做,且要避开 phpEnv 自动管理带来的覆盖风险。
为什么 phpEnv 的「网站设置」里填了跳转却没生效
phpEnv 的 Web 界面(如“强制 HTTPS”或“域名跳转”开关)底层只是生成部分配置,但不处理 server_name 分离和 return 301 的精确位置。常见失效原因:
- 界面填写的跳转规则被写进
location /块里,而 Nginx 要求域名级跳转必须在server块顶层执行 - phpEnv 会定期重写 vhost 配置(比如修改 PHP 版本、SSL 开关时),手动加的
rewrite或if容易被清掉 - 用了
if ($host != 'www.example.com') { rewrite ... }—— 这种写法在 Nginx 里是“ discouraged”,且在 phpEnv 的配置模板中常被禁用或忽略
正确做法:直接改 Nginx vhost 文件,用 return 301
进入 phpEnv 对应站点的 Nginx 配置文件(路径类似 /phpenv/vhosts/example.com.conf),在已有 server 块外,**新增一个独立的 server 块**,只监听非 www 域名:
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /phpenv/ssl/example.com.crt;
ssl_certificate_key /phpenv/ssl/example.com.key;
return 301 https://www.example.com$request_uri;
}
注意点:
- 两个
server块分别处理 HTTP 和 HTTPS 的非 www 请求,避免混合协议跳转失败 - 用
return 301而不用rewrite ... permanent:更轻量、无正则开销、Nginx 官方推荐用于简单跳转 -
$request_uri保留原始路径和参数,比$1更可靠(尤其含问号、编码字符时) - 别删掉已有的 www 主站
server块,它负责实际服务
跳转后 PHP 里获取不到真实域名?检查 $host 和 $_SERVER['HTTP_HOST']
用户访问 example.com → 301 到 www.example.com → 浏览器地址栏变了,但 PHP 接收到的仍是跳转后的域名。如果你在代码里依赖 $_SERVER['HTTP_HOST'] 做判断,它返回的是 www.example.com,不是原始请求域名。
这意味着:
- PHP 层无法感知“这次请求本来是冲着非 www 来的”,因为 301 是客户端行为,服务端只处理最终到达的那个请求
- 不要在 PHP 里重复做跳转(比如用
header("Location: ...")),否则会和 Nginx 跳转叠加,导致循环重定向 - 如果真要记录原始 host,只能靠 Nginx 在跳转前加 header(如
proxy_set_header X-Original-Host $host;),但 phpEnv 默认不启用 proxy 模式,不建议这么绕
最稳的方式就是把跳转逻辑全交给 Nginx,在 vhost 里用独立 server 块 + return 301,不碰 phpEnv 界面、不写 if、不改 PHP 代码——跳转快、可维护、不会被自动覆盖。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











