需根据SAPI环境分别修改:CLI改php.ini,FPM须在pool配置中设php_admin_value[memory_limit]并重启服务,且Web与CLI的php.ini路径不同。

phpEnv 下改 memory_limit 不能只改一个文件,得看清楚你当前用的是哪个 SAPI 环境,否则改了等于没改。
确认 phpEnv 当前生效的 php.ini 路径
phpEnv 是多版本共存环境,每个 PHP 版本(如 7.4、8.1、8.3)都有独立的 CLI 和 FPM 配置,且默认不共享 php.ini。你运行 php -i | grep "Loaded Configuration File" 看到的路径,和 Web 请求里 phpinfo() 显示的「Loaded Configuration File」往往不同——前者是 CLI 的,后者才是 Apache/Nginx + phpEnv-FPM 实际加载的。
常见误区:
- 只改了
/usr/local/phpenv/versions/8.2/etc/php.ini,但 phpEnv-FPM 实际加载的是/usr/local/phpenv/versions/8.2/etc/php-fpm.d/www.conf里指定的额外 ini 文件 - 用
phpenv global 8.2切换后,CLI 生效了,但 Web 还在跑 8.1 的 FPM pool
正确做法:在 Web 环境下建一个 info.php,内容为 <?php phpinfo(); ?>,访问它,盯住「Loaded Configuration File」和「Additional .ini files parsed」两行——你真正要编辑的就是这里列出的文件。
立即学习“PHP免费学习笔记(深入)”;
phpEnv-FPM 场景优先改 pool 配置里的 php_admin_value[memory_limit]
phpEnv 默认用 FPM + Nginx,此时直接改 php.ini 很可能被覆盖。FPM pool 配置(如 /usr/local/phpenv/versions/8.2/etc/php-fpm.d/www.conf)中这一行具有最高权限:
php_admin_value[memory_limit] = 512M
它比 php.ini 里的 memory_limit 优先级高,也屏蔽掉脚本里 ini_set('memory_limit', ...) 的修改企图——这是防止恶意或误操作脚本把内存拉爆的关键机制。
注意点:
- 改完必须执行
phpenv fpm restart或手动sudo systemctl restart php8.2-fpm(取决于你的 phpEnv 封装方式),reload有时不重载 admin_value - 不同站点可配不同 pool,比如后台 API 池设
512M,静态资源池设64M,避免一刀切 - 单位大小写敏感:
512m会被解析为 0,必须写512M或512MB
ini_set('memory_limit') 在 phpEnv 里能用,但有硬限制
在入口文件(如 index.php)开头加 ini_set('memory_limit', '256M'); 是可行的,但仅限于“调大”:
- 如果 pool 配置里用了
php_admin_value[memory_limit],这行会直接失效,连 warning 都不报 - 如果当前限制已是
256M,你再ini_set('memory_limit', '128M')会静默失败,ini_get('memory_limit')仍返回256M - CLI 下用
phpenv shell 8.2启动的脚本,可以靠它临时提限;但 Web 请求中,它只对当前 HTTP 请求生命周期有效
所以它适合做“脚本级兜底”,比如某段导出逻辑确定要 384M,就在该脚本顶部设好,而不是用来掩盖内存泄漏。
验证改没改成功,别信感觉
改完配置,立刻用这三招交叉验证:
- Web 环境:访问
info.php页面,搜索memory_limit,确认值和你设的一致 - CLI 环境:运行
phpenv shell 8.2 && php -r "echo ini_get('memory_limit').PHP_EOL;",看是否匹配预期 - 真实压力测试:跑一段已知吃内存的代码(比如
str_repeat('x', 300 * 1024 * 1024)),观察是否真报Fatal error: Allowed memory size of ... exhausted,还是撑过去了
最容易被忽略的一点:phpEnv 的 FPM 日志(通常在 /usr/local/phpenv/versions/*/var/log/php-fpm.log)里如果持续出现 unable to map pm.status_path 或 worker segfault,往往不是 memory_limit 不够,而是 OPcache 或 APCu 占用了大量未计入统计的内存——这时得同步调 opcache.memory_consumption,而不是一个劲往上提 memory_limit。



















