phpEnv需手动配置hosts文件,否则域名无法解析至本地;站点根目录须为独立一级目录;PHP-FPM应为高风险站点分池隔离;生产环境须校验HTTP_HOST白名单。

phpEnv 的 host 文件必须手动改,否则域名根本发不到 PHP
phpEnv 是 Windows 下的轻量集成环境,不带自动 hosts 管理。你点“添加站点”填了 www.site-a.com,但没改系统 C:\Windows\System32\drivers\etc\hosts,浏览器就只会去公网查这个域名——结果 404 或跳转到别人网站。
必须用管理员权限打开记事本,往 hosts 文件末尾加两行:
127.0.0.1 www.site-a.com 127.0.0.1 www.site-b.com
别漏空格,别加 http://,改完保存。如果用 VS Code 或 Notepad++ 编辑失败,换系统自带记事本并“以管理员身份运行”。
phpEnv 站点根目录不能嵌套,DocumentRoot 必须是独立文件夹
常见错误:把两个站点都放在 D:\phpenv\www\ 下,比如 D:\phpenv\www\site-a\ 和 D:\phpenv\www\site-b\,然后在 phpEnv 控制面板里填路径填成 D:\phpenv\www\site-a —— 看似合理,但 Apache/Nginx 实际启动时会因权限或重写规则错乱,导致 CSS 加载 404、$_SERVER['DOCUMENT_ROOT'] 指向错误、甚至所有请求 fallback 到默认站。
- 正确做法:每个站点用完全独立的一级目录,如
D:\sites\site-a、D:\sites\site-b - 在 phpEnv 添加站点时,“网站目录”字段必须精确选中该独立文件夹,不能多也不能少一个字符
- 确认该目录下有
index.php或index.html,且文件权限为可读(右键 → 属性 → 安全 → Users 组有“读取”权限)
PHP-FPM 池未隔离时,一个站点崩溃会导致全部 502
phpEnv 默认只启用一个 PHP-FPM 池(通常是 www),所有站点共用。某个站点代码死循环、内存溢出或慢日志塞满,会耗尽该池全部子进程,其他站点立刻返回 502 Bad Gateway,而错误日志里却只显示“connect() to unix:/tmp/php-cgi.sock failed”这类模糊提示。
解决方法是手动为每个高风险站点分池:
- 进
D:\phpenv\php\php-8.2\php-fpm.d\(路径依你选的 PHP 版本变) - 复制一份
www.conf,重命名为site-a.conf - 修改其中三处:
pool改为site-a,listen改为/tmp/php-cgi-site-a.sock,pm.max_children设为 10~20(别照抄默认 50) - 回到 phpEnv 面板,编辑站点 → “PHP 设置” → 手动指定 FPM Socket 路径为
/tmp/php-cgi-site-a.sock
改完务必点 phpEnv 上的“重启 Apache/Nginx”和“重启 PHP-FPM”,不是只点“重启服务”。
$_SERVER['HTTP_HOST'] 可伪造,生产环境不能直接当配置 key 用
本地调试时用 $_SERVER['HTTP_HOST'] 区分站点很顺手,比如 require "config/{$host}.php"。但上线后,攻击者只要发个 Host: evil.com 请求,就能让 PHP 去加载不存在的配置文件,触发警告甚至路径遍历漏洞。
必须加白名单校验:
$allowed = ['www.site-a.com', 'site-a.com', 'www.site-b.com'];
$host = $_SERVER['HTTP_HOST'] ?? '';
$host = strtolower(preg_replace('/:\d+$/', '', $host));
if (!in_array($host, $allowed)) {
http_response_code(400);
exit('Invalid host');
}
$config_key = str_replace(['www.', '.com'], ['', ''], $host); // 得到 site-a
注意:永远不用 $_SERVER['SERVER_NAME'],它来自 Apache/Nginx 配置,不是客户端真实请求头;也别用 $_SERVER['REQUEST_URI'] 做主判断,路径可能被重写干扰。
多站点最易忽略的其实是日志分离和缓存前缀。同一个 opcache 或 apcu 实例混用,不同站点的类定义可能冲突;共享 error_log 路径会让故障排查变成猜谜。每个站点的 php.ini 或 FPM 池配置里,务必单独设 error_log、opcache.validate_timestamps=0(开发关)、apc.cache_by_default=0(按需开)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











