当达到memory_limit时,PHP不会触发致命错误

时间:2017-10-06 21:47:18

标签: php out-of-memory

我有基本页面,我试图让Fatal Error, Out of memory消息显示,但是没有任何反应脚本没有错误,PHP 7.1.9没有suhosin。

ini_set("memory_limit", 100); //100 bytes.
echo "Memory Limit Bytes " . ini_get("memory_limit") . PHP_EOL;
echo "Script peak memory usage " . memory_get_peak_usage() . PHP_EOL;

输出无致命错误。

Memory Limit Bytes 100
Script peak memory usage 386960
The End

1 个答案:

答案 0 :(得分:1)

您正在利用PHP的一个非常棘手的领域。问题是,一旦你的PHP进程耗尽了内存就会结束游戏。不会抛出异常,因为致命错误会触发脚本终止。

根据我的经验,这里最好的选择是使用register_shutdown_function()来注册一个回调,它将检查error_get_last()并处理被@(闭塞)运算符静音的违规代码,或者ini_set('display_errors',假)。

如果在发生此错误时需要执行重要的清理代码,则注册关闭功能是不够的。一种方法是在PHP进程横向移动时在某处释放一些紧急内存。

<?php 
ini_set("memory_limit", 400000); //100 bytes
ini_set('display_errors', false);
error_reporting(-1);

echo("start");
echo "Memory Limit Bytes " . ini_get("memory_limit") . PHP_EOL;
echo "Script peak memory usage " . memory_get_peak_usage() . PHP_EOL;

// This storage is freed on error (case of allowed memory exhausted)
$memory = str_repeat('*', 100000);
echo("2");
set_error_handler(function($code, $string, $file, $line){
        throw new ErrorException($string, null, $code, $file, $line);
    });

register_shutdown_function(function(){
    global $memory;
    $memory = null;
    $error = error_get_last();
    if(null !== $error)
    {
        echo 'Caught at shutdown';
    }
});

try
{
    $a = '';
    for ($i=0; $i<=10000000; $i++) {
        $a .= '1';
    }
    echo("done");
}
catch(\Exception $exception)
{
    echo 'Caught in try/catch';
}
?>

查看讨论PHP内存处理的article(以及其他内容)。