12

你知道从 PHP 致命错误中恢复的任何解决方案:“允许的内存大小......用尽

我有一个关闭函数,当出现致命错误时会调用它。此函数从中创建一个 ErrorException 并记录它。

问题是:当没有更多可用内存时,它无法记录错误(我通过 FirePHP 使用 Zend Framework 登录 Firebug)。

所以我所说的“如何从中恢复”的意思是如何执行基本的错误日志,并让 Zend Framework 发送标头,以便将错误记录(在我的情况下为 Firebug)作为任何其他错误?

谢谢

4

7 回答 7

8
if((memory_get_usage() / 1024 /1024) < 70)

我只是将 memory_get_usage 除以 1024 的平方,以将其与“正常”兆字节值“70”进行比较。

我在 for 循环中遇到了 php 的内存问题,并编写了这个简单的 if 语句来防止我的脚本引发致命错误。此外,我正在运行的服务器不允许我修改内存限制(这在一些云产品(如 openshift)或大型网络主机(如 dreamhost)中经常出现。)我并没有真正注意到任何严重的性能下降(在 php 5.3 中,它处理诸如此类的函数可能与 php 4.x 或 5.x 略有不同......无论如何,给出致命错误的脚本的性能影响超过了函数调用可能强制执行的任何开销。并且还会防止消耗所有可用内存的失控脚本。

许多人可能会争论;哦,嘿,你的软件没有优化。是的。你也许是对的; 但是对于复杂的数据集,您只能在需要投入更多内存之前挤出这么多的性能;在 ajax 流中查找内存错误可能非常令人沮丧;特别是当您不确定您的日志文件在哪里时。

于 2013-02-20T23:38:57.363 回答
8

此错误是致命错误 - 这意味着您无法从中恢复。如果 PHP 已达到其内存限制,它将无法分配更多内存来创建您的异常以及执行其所需的任何其他内存。

还有另一种类型的错误 - “可捕获的致命错误”,顾名思义,可以在 try/catch 中捕获,但不幸的是内存大小分配不是其中之一。

于 2010-02-23T14:43:43.400 回答
5

自定义错误处理的常规方法是通过

set_error_handler— 设置用户定义的错误处理函数

此功能状态的文档(强调我的):

以下错误类型无法使用用户定义的函数处理:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING,以及在调用 set_error_handler() 的文件中引发的大部分 E_STRICT。

所以,它不会经常工作,但你可以试试

从 PHP7 开始,错误和异常是 Throwables,因此您可以尝试/捕获它们:

于 2010-02-23T14:51:56.863 回答
2

有一个未经测试的技巧的想法,我很高兴知道它是否有帮助。首次注册关闭函数时分配一些全局变量,并在首次执行关闭函数的代码时释放它。然后,您可能有足够的内存来创建 Exception 对象。让我知道它是否有效,请在此处发布代码。

于 2010-04-22T17:28:00.403 回答
2

这对我来说很好:

try {
    ini_set('memory_limit', (ini_get('memory_limit')+1).'M');
} catch(Exception $e) {}

这假设您的内存限制为格式123M

于 2011-11-23T14:28:49.267 回答
2

PHP 错误默认发送到您的 apache 错误日志/path/to/apache/logs/error.log,您可以在那里看到它。

于 2010-02-23T14:36:50.060 回答
1

我能想到的一个方法是,当您进行内存密集型操作时,您会memory_get_usage()定期手动查询(例如,每次循环迭代)并在超出某个低于脚本限制的故障安全值时转储您的标头/错误. 它会大大降低你的脚本速度,但至少你会得到一些回报。

或者,您可能无法执行此操作,将内存密集型内容作为基于 CLI 的脚本运行,该脚本通过使用 exec 从基于 Web 的内容内部调用。CLI 部件可能会倒下,但 Web 部件将能够报告它。

于 2010-02-23T15:05:25.377 回答