.env文件本身路径隔离不冲突,但env()函数依赖getenv()读取全局环境变量,易被Shell、FPM池或父进程污染,导致多项目配置错乱。

多个 Laravel 项目共用 phpEnv(或类似多版本 PHP 环境管理工具)时,.env 文件不会直接冲突,但 env() 函数读取行为会被外部环境变量覆盖 —— 这才是实际冲突根源。
为什么 .env 文件本身不冲突,却总出问题?
Laravel 启动时通过 Dotenv 加载当前项目根目录下的 .env,这一步是路径隔离的,没问题。但 env('DB_HOST') 实际返回值 = getenv('DB_HOST') ?: $default,而 getenv() 会优先读取系统级、Shell 级或父进程传入的环境变量 —— 这些是全局的。
- 你在终端里执行
export APP_ENV=production后再启动两个项目,它们都会读到这个APP_ENV - 宝塔面板中若多个站点共用同一个 PHP-FPM 池,且未在各自池里显式设置
APP_ENV,FPM 子进程可能继承上一个项目的环境变量 - 使用
php -S启动时,PHP 内置服务器不加载php.ini中的variables_order配置,$_ENV和getenv()行为更不可控
phpEnv 下必须隔离的三个关键点
phpEnv 本身不管理环境变量,它只切换 PHP 可执行文件路径。真正要动手的是运行时上下文:
-
APP_ENV必须由每个项目独立声明:要么在项目根目录下加.env文件并确保它存在,要么在启动命令前加APP_ENV=local php artisan serve - 避免在 Shell 全局
export:不要在~/.bashrc或/etc/environment里写export DB_*类变量 - 检查
phpinfo()页面里的Environment区域 —— 这里显示的是实际被getenv()读到的值,不是.env文件内容
php artisan serve 多项目端口与环境隔离实操
这是本地开发最轻量、最可靠的隔离方式,无需改配置、不依赖 Web 服务器:
立即学习“PHP免费学习笔记(深入)”;
- 进第一个项目
public/目录,运行:APP_ENV=local php -S 127.0.0.1:8001 -t . router.php - 进第二个项目
public/目录,运行:APP_ENV=staging php -S 127.0.0.1:8002 -t . router.php - 注意:必须显式传
APP_ENV,否则 Laravel 默认 fallback 到production,且该值会被后续所有同 Shell 的php artisan命令继承 - 如果报
Address already in use,用lsof -t -i:8001查 PID,再kill -9杀掉,别靠关终端 —— 某些终端模拟器(如 Windows Terminal)会把进程转为后台继续跑
真正麻烦的从来不是 .env 文件位置,而是 getenv() 被谁污染了。每次看到配置不对,先看 phpinfo() 里 Environment 表格,比翻十遍 .env 都管用。



















