php 7+ 中 safe_mode 已被彻底移除,排查 exec 失败应检查 disable_functions、selinux/apparmor、容器安全策略及执行上下文权限,而非寻找已不存在的 safe_mode 配置。

PHP 源码里调用 exec、shell_exec 等函数失败,不是改个 safe_mode 就能解决的——因为 safe_mode 早在 PHP 5.4.0 就被彻底移除了,继续找它纯属白费功夫。
PHP 7+ 中根本不存在 safe_mode,别再查 php.ini 里的 safe_mode = Off
很多老教程还在提 safe_mode,但这是历史包袱。PHP 5.4 起该配置项已被删除,解析时直接报错:Unknown directive 'safe_mode'。如果你在 php.ini 里还留着这行,PHP 启动会失败或静默忽略(取决于 SAPI 和错误报告级别)。
- 检查是否真有残留:运行
php -i | grep safe_mode,输出为空才对 - PHP 7.0+ 用户请直接删掉 php.ini 中所有含
safe_mode的行 - 替代思路是用
disable_functions或open_basedir控制执行能力,而非“开启 safe_mode”
真正拦住 exec 的通常是 disable_functions 或 SELinux/AppArmor
最常见原因不是“模式没开”,而是函数被显式禁用,或系统级安全策略拦截了子进程创建。
- 查当前禁用函数:
php -i | grep disable_functions,确认exec、shell_exec、system是否在列表里 - 若在,需在 php.ini 中清空或删掉对应函数名,例如:
disable_functions = pcntl_alarm,pcntl_fork,...→ 把exec从中剔除 - Linux 上还要看 SELinux 是否启用:
sestatus;若为 enforcing,Web 进程可能无权执行 shell,临时测试可setenforce 0(不推荐生产环境) - 某些容器或托管环境(如 cPanel、Plesk)还会通过 suhosin 或 mod_security 二次拦截,需单独排查
exec 执行成功但没回显?注意输出捕获方式和权限上下文
即使函数没被禁,也常因权限、路径、输出重定向问题看似“没反应”。
立即学习“PHP免费学习笔记(深入)”;
-
exec('ls')默认不返回输出,要用exec('ls', $output, $return_code)或改用shell_exec('ls') - Web 服务器用户(如
www-data或apache)执行命令,跟终端登录用户权限不同,sudo几乎肯定失败,别硬加 - 绝对路径优先:
/bin/ls比ls可靠,因为 Web 进程的$PATH通常极简 - 命令含空格或特殊字符时务必用
escapeshellarg()包裹参数,否则可能被截断或注入
真正卡住的地方往往不在 PHP 配置本身,而在函数是否被禁、系统策略是否放行、以及执行上下文有没有对应权限——盯着 safe_mode 找问题,等于在废弃的火车站等高铁。











