[PHP] Memory Leaks and Timeouts Cannot Be Caught by Exception Handling! So, What Should We Do?

PHP
スポンサーリンク

Introduction

As the title suggests, errors like memory leaks (memory_limit) and timeouts (max_execution_time) are considered Fatal errors, meaning they cannot be caught by the try-catch exception handling. A Fatal error causes the script to terminate.

So, how do we handle these errors?

In conclusion, by using PHP’s built-in register_shutdown_function, you can detect errors that occur when the script ends, allowing for proper error handling.

Using register_shutdown_function

Below is a sample code.

<?php
// Define register_shutdown_function before the implementation code
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error !== NULL) {
        if (strpos($error['message'], 'Allowed memory size') !== false) {
            // If a memory leak occurs
            error_log("Memory leak occurred error-message: " . $error['message']);
            header("Location:https://yourwebsite.com/memory-leak-error-page");
            exit();
        }
        if (strpos($error['message'], 'Maximum execution time') !== false) {
            // If a timeout occurs
            error_log("Timeout occurred error-message: " . $error['message']);
            header("Location:https://yourwebsite.com/timeout-error-page");
            exit();
        }
    }
});


// Intentionally cause a Fatal error
ini_set("max_execution_time", 2);
ini_set('memory_limit', '2M');
// Generate a large array to consume a lot of memory
$data = [];
for ($i = 0; $i < 1000000; $i++) {
    $data[] = str_repeat('a', 1024 * 1024);
}

// Write the code that should be implemented here
var_dump("In this case, this code will not be reached, and register_shutdown_function will be called");
exit();

The sample above is implemented using an anonymous function (closure) with register_shutdown_function. Although many samples found online use the following form, it seems possible to implement it with an anonymous function (closure) as well.

<?php
function shutdown()
{
    // Write the processing that occurs during shutdown here (e.g., output logs, redirect to an error page, etc.)
    echo 'Script executed with success', PHP_EOL;
}

register_shutdown_function('shutdown');

rReference link about register_shutdown_function

PHP: register_shutdown_function - Manual

Even with try-catch and Throwable, memory leaks and timeouts can’t be caught, which has been quite troublesome. But finally, this resolves the issue.

タイトルとURLをコピーしました