真实生效路径是“loaded configuration file”行所示路径;web用phpinfo()查,cli用php --ini查;disable_functions须小写、逗号分隔无空格、不换行无注释、末尾无逗号;fpm池配置php_admin_value[disable_functions]优先级更高;改完必须重启服务并用putenv/exec实测验证。

PHP 8.1.27 生产环境禁用 putenv 等危险函数,核心不是“加一行配置”,而是确保该配置**精准作用于真实运行的 PHP 实例**,且语法零容错、验证无死角。
确认当前生效的 php.ini 路径
Web 请求和命令行(CLI)加载的配置文件不同,必须分别确认:
- Web 环境:新建
info.php,内容为<?php phpinfo(); ?>,访问后搜索 “Loaded Configuration File” —— 这才是 Nginx+PHP-FPM 或 Apache 实际读取的路径,如/etc/php/8.1/fpm/php.ini - CLI 环境:执行
php --ini,看 “Loaded Configuration File” 行,常见路径如/etc/php/8.1/cli/php.ini - 宝塔、Docker、phpEnv 等环境常有多个配置副本,务必以
phpinfo()或php --ini输出为准,别凭经验改错文件
在 php.ini 中正确填写 disable_functions
找到已确认的 php.ini 文件,定位或新增 disable_functions 行。针对 PHP 8.1.27,推荐禁用以下函数(含 putenv):
disable_functions = exec,system,shell_exec,passthru,proc_open,popen,pcntl_exec,putenv,ini_set,eval,assert,file_put_contents,symlink,copy,chown,chgrp,dl
- 全部小写,逗号为唯一分隔符,逗号后绝对不能有空格(
putenv, ini_set❌ 会失效) - 不能换行,不能加注释(
;后内容被截断) - 末尾不能有逗号(
dl,❌ 导致整行解析失败) -
putenv必须显式列出——它可篡改环境变量,配合某些扩展(如 ImageMagick、某些日志库)可能触发反序列化或命令注入
PHP-FPM 池配置必须同步覆盖
Nginx + PHP-FPM 架构下,www.conf 中的 php_admin_value[disable_functions] 优先级高于 php.ini,漏配即被绕过:
- 编辑对应 pool 文件,如
/etc/php/8.1/fpm/pool.d/www.conf - 添加或取消注释该行:
php_admin_value[disable_functions] = exec,system,shell_exec,passthru,proc_open,popen,pcntl_exec,putenv,ini_set,eval,assert,file_put_contents,symlink,copy - 确保该行未被
;注释,且无拼写错误或尾部逗号 - 若使用宝塔,配置通常在
/www/server/php/81/etc/php-fpm.d/www.conf;Docker 中需挂载并修改容器内对应文件
重启服务并实测验证
改完不重启=白改,reload 不重读 disable_functions:
- 执行
sudo systemctl restart php8.1-fpm(FPM)或sudo systemctl restart apache2(Apache) - CLI 测试:
/usr/bin/php8.1 -r "var_dump(putenv('PATH=/tmp'));"→ 应输出NULL并报Warning: putenv() has been disabled for security reasons - Web 测试:在
info.php同目录建test.php,内容为:<?php <br> var_dump(putenv('TEST=1'));<br> var_dump(exec('id'));<br> ?>
访问后页面应显示两行NULL并带 Warning,而非静默返回或执行成功 - 检查运行时列表:
php -r "print_r(get_disabled_functions());",确认putenv在输出数组中
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











