DEV Community

Cover image for Streaming Large Files with PHP to Save Memory
Accreditly
Accreditly

Posted on • Originally published at accreditly.io

Streaming Large Files with PHP to Save Memory

Handling large files is a common task for web developers. However, if not done properly, it can lead to high memory usage and slow performance. In this tutorial, we will look at how to stream large files to the browser in a memory-efficient way using PHP.

Prerequisites

  • Basic knowledge of PHP
  • An active PHP development environment

Step 1: File Streaming Basics

Before we dive into the code, let's first understand what file streaming is. When you open a file in PHP with fopen(), you can read it line by line or character by character with fgets() or fgetc(), instead of loading the entire file into memory. This is known as file streaming.

Step 2: Setting Up the PHP Script

Let's create a new PHP script, download.php. In this script, we will:

  1. Open the file we want to stream.
  2. Read a portion of the file and output it to the browser.
  3. Repeat step 2 until the entire file has been read and sent.

Here's the code:

<?php
$file = 'path/to/your/largefile.pdf';

// Make sure the file exists
if (!file_exists($file)) {
    die('File not found.');
}

// Set headers to tell the browser to download the file
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));

// Open the file in binary mode
$fp = fopen($file, 'rb');

// Output the file
while (!feof($fp)) {
    // Read and output a chunk of the file
    echo fread($fp, 8192);

    // Flush the output buffer to free up memory
    ob_flush();
    flush();
}

// Close the file
fclose($fp);
exit;
Enter fullscreen mode Exit fullscreen mode

In the above code, we use fopen() to open the file and fread() to read a chunk of 8192 bytes at a time (which is approximately 8KB). We then output this chunk using echo and flush the output buffer to free up the memory used. This process repeats until the end of the file (feof($fp) returns true).

In this tutorial, you've learned how to stream large files to the browser in a memory-efficient way using PHP. This method is very useful when dealing with large files that could otherwise consume significant server memory and lead to performance issues. Always remember to close any open file handles and flush the output buffer to free up memory.

Top comments (3)

Collapse
 
gshapira profile image
Gabriel Shapira

I have added output buffer settings. ob_flush() seems to work, but still cannot
transfer 500Mg files.

@ini_set('output_buffering','Off');
@ini_set('zlib.output_compression',0);
@ini_set('implicit_flush',1);
@ob_end_clean();
set_time_limit(0);
ob_start();
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gshapira profile image
Gabriel Shapira

Did not work:
Got error "PHP Notice: ob_flush(): failed to flush buffer. No buffer to flush in download.php on line 8"
$handle = fopen($file_path, 'rb');
if ($handle === false) {
die("Could not open file. Check access controls");
}
while (!feof($handle)) {
//@@@print(fread($handle, 1024*8));
echo fread($handle, 1024*8);
ob_flush();
flush();
}
$status = fclose($handle);

Collapse
 
srsbiz profile image
Radosław Kowalewski

For simple reading whole file there is built-in function, which is already memory-safe php.net/manual/en/function.readfil...