宝塔面板无法通过界面删除putenv和proc_open,因其被硬编码进底层配置模板;需手动编辑对应PHP版本的php.ini文件中disable_functions项并重载配置才能生效。

宝塔面板里删不掉 putenv 和 proc_open?因为它们被硬编码进全局禁用列表
直接在面板 PHP 设置界面删除 putenv、proc_open 等函数,保存后重启 PHP 仍会自动恢复——这不是你操作错了,而是宝塔从 7.9+ 版本起,把部分高危函数写死在底层配置模板中,Web 界面的“禁用函数”字段仅追加,不覆盖。
真正生效的禁用函数是两部分拼接的结果:disable_functions 配置项(你填的) + 宝塔内置白名单过滤逻辑(它硬加的)。而 putenv 和 proc_open 正好属于后者,无论你在面板里清空还是留空,都会被自动补上。
- 检查方法:执行
php -i | grep disable_functions,输出里必然包含这两个函数 - 影响范围:所有通过宝塔创建的 PHP 站点(包括不同版本),只要没手动绕过
- 根本原因:宝塔为防 shell_exec 类漏洞,默认锁定这些函数,且不提供界面开关
绕过宝塔硬编码限制的唯一可靠方式:手动编辑 PHP 配置文件
必须跳过面板界面,直接修改对应 PHP 版本的 php.ini 文件。注意不是网站根目录下的 .user.ini,那是子级覆盖,压不住宝塔的全局注入。
- 找到真实配置路径:一般为
/www/server/php/{版本号}/etc/php.ini(例如/www/server/php/80/etc/php.ini) - 搜索
disable_functions行,把整行替换成你想要的值,例如:disable_functions = exec,passthru,shell_exec,system,proc_get_status,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server
(去掉putenv和proc_open) - 保存后,**必须执行
bt 16或在面板「软件商店 → PHP → 设置 → 服务 → 重载配置」**,单纯重启 PHP 进程不够 - 验证是否生效:新建一个
info.php,内容为<?php phpinfo(); ?>,浏览器访问,搜索disable_functions看输出是否已更新
解除限制后要注意的兼容性与安全事实
很多 Composer 包、Laravel 的队列驱动、甚至某些 CMS 的环境检测,确实依赖 putenv 或 proc_open。但放开不等于安全无虞,得清楚代价。
-
proc_open解禁后,任何 PHP 脚本都能启动子进程,若站点存在代码执行漏洞(如反序列化、模板注入),攻击者可直接调用bash、python等系统命令 -
putenv单独解禁风险较低,但配合其他函数(如mail()或扩展)可能绕过某些环境隔离逻辑 - 如果你只是跑 Laravel Sail 或本地开发镜像,建议只在测试环境改;生产环境应优先查清具体哪个包报错,再针对性用
ini_set('disable_functions', '')在入口文件临时覆盖(不推荐长期用)
为什么不用宝塔的“禁用函数白名单”功能?它根本不存在
网上有文章说“在面板设置里勾选‘允许使用’就能放行”,纯属误导。宝塔没有函数级白名单机制,只有全局禁用列表,且对特定函数强制保留。所谓“白名单”是用户臆想或混淆了 Nginx 的 fastcgi_param 传递逻辑。
更麻烦的是:升级宝塔或 PHP 插件时,php.ini 可能被重置。所以每次升级后,都得重新检查 disable_functions 行是否又被加回 putenv 和 proc_open —— 这是最容易被忽略的一环。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











