skip to Main Content

This question comes from an issue I’ve ran it.

The server is supposed to die() with a file in the message, but doing this allocates too much memory for the script and it throws a Fatal Error.

Is this intended behavior? The string is passed to it so why does it make an copy of it? Are there any smart workarounds to this that wouldn’t be to just increase the memory cap?


Here is a small PoC that i made to demo the issue. It’s not the best but as smart as I could figure out in 10 minutes.

It throws Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes) in mem_tester.php on line 11

<?php

// set this to whatever it says currently using is if you start from 0
$mem = 0;
ini_set('memory_limit', $mem);

// might need more repeats if it does not crash
$str = str_repeat(".", $mem / 2);
//echo $str; // this also allocates
//exit($str); // same as die, but for certainty
die($str);

2

Answers


  1. The behavior you’re seeing is due to the way PHP handles memory allocation when outputting data, especially large strings. When you call die($str), PHP attempts to output $str to the browser, and this process can consume additional memory beyond what is already allocated to store $str itself.

    Potential Workarounds

    Use echo and die() Separately: By separating the output and the termination, you may reduce some of the additional memory allocation. Try this:

    echo $str;
    die();
    

    Write to a File Instead of Outputting: For large strings or heavy debugging, consider writing $str to a file and then terminating:

    file_put_contents('/path/to/log.txt', $str);
    die("Output saved to log file.");
    

    Hope this helps!

    Login or Signup to reply.
  2. You could split the data into chunks and output it seperatly:

    $size = $mem / 2;
    while ($size > 0) {
        $chunk = min(8192, $size); // Process 8KB at a time
        echo str_repeat(".", $chunk);
        $size -= $chunk;
    }
    exit();
    

    Or use PHP streaming capabilities:

    $stream = fopen('php://output', 'w');
    $size = $mem / 2;
    while ($size > 0) {
        $chunk = min(8192, $size);
        fwrite($stream, str_repeat(".", $chunk));
        $size -= $chunk;
    }
    fclose($stream);
    exit();
    

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search