应先通过 phpinfo() 确认 apache 实际加载的 php.ini 路径,再在该文件的 [php] 段正确配置 disable_functions(无空格、英文逗号分隔),并完整重启 apache 服务;同时需同步修改 cli 对应的 php.ini,并启用 phar.readonly 和 phar.require_hash。

确认当前生效的 php.ini 路径
改错文件等于没改。XAMPP 中 Apache 和 CLI(命令行)可能加载完全不同的 php.ini,尤其在升级或重装后容易混淆。直接去 C:\xampp\php\php.ini 修改,但 Apache 实际加载的可能是 C:\xampp\apache\bin\php.ini(取决于 PHPIniDir 配置)。
务必先建一个 info.php 放到 htdocs 下,内容为 <?php phpinfo(); ?>,用浏览器访问 http://localhost/info.php,搜索 Loaded Configuration File —— 这个路径才是你该编辑的文件。
修改 disable_functions 并注意格式细节
disable_functions 必须写在主配置段([PHP] 区域内),不能放在扩展区块或注释块里;值必须用英文逗号分隔,绝对不能加空格,否则 PHP 会静默忽略整行。
常见危险函数建议禁用:
-
exec,system,shell_exec,passthru -
proc_open,popen,pcntl_exec - 如需更严格,可追加
curl_exec,curl_multi_exec,parse_ini_file,show_source
示例写法(无空格、无引号、不换行):disable_functions = exec,system,shell_exec,passthru,proc_open,popen,pcntl_exec,curl_exec,parse_ini_file
重启服务并验证是否真正生效
只点“Restart”或“Reload”不够,XAMPP 控制面板必须对 Apache 执行完整 Stop → Start 流程,否则 opcache 不刷新、disable_functions 不重载。
验证不能只看函数返回 NULL 或空字符串——禁用成功时,调用会触发 Warning:Warning: exec() has been disabled for security reasons。
写个测试脚本确认:
<?php var_dump(exec('echo 1'));
var_dump(shell_exec('whoami'));
?>
同时运行 CLI 验证:php -r "echo shell_exec('id');",若 CLI 没禁用,说明你漏改了 php --ini 显示的 CLI 配置路径下的 php.ini。
别忽略 PHAR 和 CLI 场景的连带影响
disable_functions 不影响 phar.readonly 或 phar.require_hash,但这两项是另一层安全防线,建议同步开启:phar.readonly = Onphar.require_hash = On
CLI 模式下,disable_functions 生效逻辑与 Web 完全一致,但很多人只优化了 Apache 的配置,忘了 php --ini 查出的 CLI ini 路径(通常是 C:\xampp\php\php.ini)也要同步改。另外,get_disabled_functions() 可在代码中动态检查当前禁用列表,适合做运行时兜底判断。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











