PHP Fatal Error: Allowed Memory Size — 打破迷思并进行配置

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么你的 PHP 脚本会“崩溃”?

\n\n

你是否曾在屏幕上看到一片空白,并附有令人胆寒的提示 “Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted”?如果是——你并不孤单。这个问题在 Stack Overflow 上获得了数千次浏览,几乎每个 PHP 开发者在其职业生涯中都至少遇到过它一次。

\n\n

数字 134217728 字节 正好是 128 兆字节(许多主机商的默认限制)。当你的脚本试图占用更多内存时——PHP 会说“停”并抛出致命错误。但别急着惊慌!在本文中,我们将分析为什么会发生这种情况,如何修复,以及最重要的是——如何优化性能,使内存错误不再困扰你。

\n\n

本文是为教育网站 PythonLib 编写的,但所有代码和示例均使用 PHP。我们开始吧!

\n\n

什么是 memory_limit,以及“134217728”从何而来?

\n\n

在 PHP 中,有一个指令 memory_limit,它设置单个脚本可用的最大内存量。在许多配置中(尤其是在共享主机上),默认值为 128M(即 134217728 字节)。

\n\n

你可以这样检查当前限制:

\n\n
<?php\necho ini_get('memory_limit'); // 输出,例如 "128M"\n?>
\n\n

当你的脚本超过此限制时——PHP 会立即终止执行并抛出致命错误。原因可能各不相同:从代码效率低下到将巨大文件加载到内存中。

\n\n

导致错误的典型场景

\n\n
    \n
  • 处理大型数组——例如,将整个 CSV 文件读入内存。
  • \n
  • 存在泄漏的循环——忘记释放变量或使用全局数组。
  • \n
  • 图像处理库——GD 或 Imagick 在处理高分辨率照片时。
  • \n
  • 递归函数——没有基本情况会导致无限递归并耗尽堆栈。
  • \n
  • ORM 和缓存——某些 ORM(例如 Doctrine)可能会将整个表加载到内存中。
  • \n
\n\n

如何修复错误:3 种经过验证的方法

\n\n

1. 通过 ini_set() 临时增加限制

\n\n

最快的方法——直接在脚本中增加限制:

\n\n
<?php\nini_set('memory_limit', '256M');\n// 现在脚本最多可以使用 256 MB\n?>
\n\n

重要提示: 这仅在您的主机允许覆盖指令时才有效。在某些主机上,针对 memory_limit 的 ini_set() 是被禁止的。

\n\n

2. 修改 php.ini 或 .htaccess

\n\n

如果您可以访问服务器,请编辑 php.ini:

\n\n
memory_limit = 256M
\n\n

或者通过 .htaccess(在 Apache 上):

\n\n
php_value memory_limit 256M
\n\n

更改后,重启 Web 服务器或 PHP-FPM。

\n\n

3. 代码优化——最佳方法

\n\n

增加限制是一种权宜之计。真正的解决方案是编写高效的代码。让我们看一些例子。

\n\n

实际示例:处理大型 CSV 文件

\n\n

假设您有一个包含 500,000 行的 CSV 文件。一个简单的代码可能如下所示:

\n\n
<?php\n$rows = file('data.csv'); // 将整个文件加载到内存中!\nforeach ($rows as $row) {\n    // 处理\n}\n?>
\n\n

当文件大小为 200 MB 时——脚本会因内存错误而崩溃。

\n\n

优化:逐行读取

\n\n
<?php\n$handle = fopen('data.csv', 'r');\nif ($handle) {\n    while (($row = fgetcsv($handle)) !== false) {\n        // 一次处理一行\n        // 内存几乎不增长\n    }\n    fclose($handle);\n}\n?>
\n\n

现在,无论文件大小如何,脚本仅使用几兆字节的内存。

\n\n<

博客

书籍推荐