composer 本身不篡改 $_env 或调用 putenv(),而是依赖包在 scripts 或 autoload-dev 中主动执行此类操作;定位需先禁用脚本(--no-scripts)确认源头,再逐个排查钩子与自动加载类。

composer install 为什么悄悄改了 $_ENV 或 putenv?
不是 Composer 本身在篡改,而是你依赖的某个包在 scripts 里调用了 putenv()、$_ENV['FOO'] = 'bar' 或执行了 shell 命令(如 export FOO=bar),这些操作会污染当前 PHP 进程的运行时环境。Composer 不拦截也不审计这类行为——它只负责执行脚本。
常见触发点:
-
composer.json中根项目定义了"post-install-cmd": "php -r \"putenv('DEBUG=1');\"" - 某 dev-only 包(如测试工具)在
autoload-dev加载的类里写了putenv('APP_ENV=local') - 第三方插件(如
hirak/prestissimo旧版)在初始化时覆盖了HTTP_PROXY等网络相关变量
如何定位是哪个包在改环境变量?
用 composer run-script --list 查所有注册脚本,但更有效的是在执行时加钩子观察:
- 运行
COMPOSER_NO_INTERACTION=1 composer install --no-scripts,如果环境变量不再被改,说明问题出在脚本里 - 再逐个启用脚本:先
composer install --no-plugins --no-scripts,确认干净 baseline;然后手动执行composer run-script post-install-cmd,每跑一个就php -r "var_dump(getenv('YOUR_VAR'));"检查 - 重点盯
vendor/下每个包的composer.json的scripts字段,尤其注意pre-*和post-*钩子
别忽略 autoload-dev 引入的类——它们可能在 composer dump-autoload 后就被加载,早于脚本执行。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
为什么 getenv() 看不到变化,但 $_ENV 能看到?
PHP 的 getenv() 默认只读取进程启动时继承的环境变量,而 putenv() 修改的是内存副本,$_ENV 则是 PHP 运行时维护的映射表,默认同步更新。所以:
-
putenv('FOO=bar')→$_ENV['FOO']立刻变,getenv('FOO')仍为空(除非你设了putenv后又调getenv且没禁用variables_order) - 某些框架(如 Laravel)会主动把
$_ENV合并进配置,导致你以为“系统变量被改”,其实是应用层读了 PHP 内存态 - 验证是否真被篡改:在脚本执行前后分别运行
php -r "print_r(array_keys(\$_ENV));"对比输出
怎么防止第三方包随意改环境变量?
没有一刀切的开关,但可分层防御:
- CI/CD 中强制加
--no-scripts,再用显式命令分步执行可信脚本(如只跑dump-autoload) - 在
composer.json的config里加"allow-plugins": false,禁用所有插件——很多插件会在初始化时调putenv - 本地开发时,用
php -d variables_order=EGPCS your-script.php控制$_ENV是否可写(E表示 environment,去掉它就无法通过$_ENV修改) - 最根本的是审计依赖:对
composer.lock中可疑包(如非主流工具、高 star 低 commit 频率)检查其composer.json和autoload文件,搜索putenv、$_ENV\[、exec(.*export)
真正麻烦的不是变量被改,而是改完后没日志、不报错、只在特定路径下生效——比如只影响 CLI 而不影响 FPM,这种差异最容易漏检。










