PHP dynamic download showing error' memory limit instead of downloading file

62 Views Asked by At

Im build PHP download dynamically using this code

<?php
include '../wp-config.php';
global $wpdb;

$allowed=false;
$user_login=wp_get_current_user();
$usersn=explode(".",str_replace("http://","",$user_login->user_url));
$usermesin=$usersn[0];

if(strtoupper(trim($usermesin))=='ALLN' || strtoupper(trim($usermesin))=='TES'){
    $allowed=true;
}

// Define the directory where your files are stored
$fileDirectory = 'downloads/';

// Get the file name from a query parameter (e.g., ?file=example.txt)
$fileName = isset($_GET['file']) ? $_GET['file'] : '';

// Check if the file exists in the directory
if (!empty($fileName) && file_exists($fileDirectory . $fileName)) {
    $filePath = $fileDirectory . $fileName;
    
    // Set the appropriate headers for the download
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . (($allowed)? basename($filePath) :'permission-denied.txt') . '"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($filePath));
    
    // Output the file for download

    if($allowed){
        readfile($filePath);
    }else
    {
        echo"You don't have permission to download this file";
    }
    exit;
    // echo 'dapat file '.(($allowed)?'software' :'permission-denied.txt');
} else {
    // Handle file not found, e.g., display an error message
    echo 'File not found.';
}
?>

But this showing

Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 427106304 bytes) in /home/bengke28/public_html/wp-includes/functions.php on line 5349

Instead of downlod the file, when I run this code locally it work as expected because I change the memory limit, how to proper way to read file?

1

There are 1 best solutions below

2
On

"Allowed memory size exhausted," indicates that PHP script is trying to allocate more memory than the allowed limit.

In your case,readfile function causing the problem. This can happen when you're trying to read and output a large file, and the script is running out of memory to handle it.

To fix this issue and efficiently serve large files, instead of using readfile, you can use fread and echo to stream the file in smaller chunks. This will prevent the script from attempting to load the entire file into memory at once. It reads and streams the file in smaller chunks (8KB in this example) to prevent exhausting the memory.

Here's a modified version of your code that uses this approach:

if ($allowed) {
    $chunkSize = 8192; // Set the chunk size here
    $file = fopen($filePath, 'rb');
    while (!feof($file)) {
        echo fread($file, $chunkSize);
        flush(); // Flush the output buffer to the browser
    }
    fclose($file);
} else {
    echo "You don't have permission to download this file";
}