HOWTO · PHP
PHP ini_set 内存限制
选择脚本级或共享的 PHP 内存限制,检查实际生效的值,并验证修改结果。
本页内容
PHP 的 memory_limit 设置限制脚本可分配的内存量。合适的数值和修改位置取决于应用程序及 PHP 运行环境。许多安装环境的内存已足以满足工作负载,因此应先检查实际生效的值,并确认哪些脚本需要修改。请选择能够解决问题的最小影响范围:只修改一个脚本的设置仅对当前请求生效,而修改 php.ini 则可能影响使用该配置的多个脚本。(ini_get())
选择合适的修改范围
如果只有一个脚本需要不同的限制值,且运行环境允许修改该设置,请使用 ini_set()。这样可以让调整紧贴需要它的代码。如果 PHP 运行环境读取的配置文件需要为其服务的脚本统一应用相同限制,请使用 php.ini。共享设置可能影响无关的应用程序,因此提高限制前应考虑它们的内存用量。不要假设所有主机的默认值都相同,也不要认为一定需要提高限制。
有些主机会通过 .htaccess 或控制面板提供其他配置方式。能否使用这些方式取决于服务器、PHP 处理程序和托管政策。它们因主机而异,使用前请查阅服务提供商的说明。
检查当前 PHP 内存限制
在与受影响脚本相同类型的 PHP 进程中调用 ini_get("memory_limit")。该函数会返回此进程实际生效的值;命令行 PHP 和 Web 请求中的值可能不同。对于 Web 应用,可以暂时在相关请求中显示或记录该值,诊断完成后再移除这些输出。避免在公开页面上泄露配置详情。
返回值是 PHP 配置值,例如带单位后缀的大小。请将它与应用程序的实际需求以及 PHP 进程可用的内存进行比较。提高配置的限制不会增加物理内存,也不能保证主机能够满足每次内存分配请求。
使用 ini_set() 提高单个脚本的限制
将设置名称和非空的大小值(例如 256M)传给 ini_set()。如果 PHP 接受了修改,函数会返回之前的值;如果 PHP 无法应用修改,则会返回 false。之后再次读取设置,让脚本报告实际生效的值,而不是假定修改已成功。
请在 PHP 进程中运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
<?php
$before = ini_get('memory_limit');
$previous = ini_set('memory_limit', '256M');
$after = ini_get('memory_limit');
echo "Before: {$before}\n";
echo 'Change accepted: ' . ($previous !== false ? 'yes' : 'no') . "\n";
echo "Effective limit: {$after}\n";
Before: -1
Change accepted: yes
Effective limit: 256M
此示例报告的是它自身进程观察到的值;初始值会因安装环境而异。脚本级修改成功后仅对当前请求生效,不会更新共享配置。如果返回值表示 PHP 未应用修改,请依据实际生效的值进行诊断,并检查运行环境或主机施加的限制。代码块和输出块保持原样,其中显示的 “Before”、“Change accepted” 和 “Effective limit” 标签仍为英文。
在 php.ini 中修改共享限制
首先,确认服务于受影响脚本的 PHP 运行环境加载了哪个 php.ini 文件。PHP 安装环境可能为命令行进程和 Web 进程使用不同的配置文件,服务器也可能加载其他配置。请查看运行环境提供的配置信息或托管服务商的文档,以确认当前使用的文件;不同操作系统和安装环境没有通用的文件路径。
在当前使用的文件中找到 memory_limit 指令,并设为所需值,例如 memory_limit = 256M。保存文件后,按照 PHP 服务或托管服务商的说明使配置变更生效。具体操作取决于 PHP 的托管方式,因此不要假设所有环境都采用相同的重启步骤。
此修改可能影响使用该配置的多个脚本。如果只有一个应用程序或请求需要更高的限制,请优先采用获准的脚本级修改或主机支持的单站点设置。.htaccess 和控制面板选项并非所有环境都支持;使用前请确认相应服务器确实提供该功能。
验证实际生效的限制并排查问题
修改设置后,在受影响的脚本或请求中调用 ini_get("memory_limit"),并将结果与目标值比较。修改共享配置时,应通过读取该配置的同一 Web 或命令行运行环境进行验证。检查另一个 PHP 可执行文件可能会看到不同的配置,进而误以为修改没有生效。
如果值没有变化,请确认编辑的是该运行环境实际加载的文件、PHP 服务或主机已应用修改,以及主机允许在此范围设置该指令。对于 ini_set(),请检查其返回值,然后查看实际生效的设置。如果值已正确生效,但应用程序仍然耗尽内存,请检查其工作负载和实际内存用量;单纯提高上限可能无法解决根本原因。限制值应与进程可用的资源相匹配。
参考资料: