PHP readfile() Function

PHP

PHP readfile() - Read and Output File

The readfile() function in PHP is a powerful and straightforward way to read a file and immediately write its contents to the output buffer. This makes it ideal for file streaming use cases such as serving images, downloads, PDFs, or any other file directly to the browser.

Introduction

In the realm of PHP filesystem functions, readfile() stands out for its simplicity and efficiency in serving files directly without loading the entire content into memory first. This tutorial will explore how to use readfile(), provide real-world examples, highlight best practices, and prepare you for interview questions focused on this function.

Prerequisites

  • Basic knowledge of PHP syntax and functions
  • Familiarity with file handling concepts in PHP
  • A local or remote PHP server environment set up
  • Access to create and read files in your PHP project directory

Setup Steps

  1. Ensure your PHP environment (like XAMPP, WAMP or LAMP) is running.

  2. Create or have a sample file available on the server to read, e.g., example.txt.

  3. Create a PHP file to implement readfile().

  4. Write the PHP script to read and output the file contents.

Understanding PHP readfile() Function

The readfile() function reads a file and writes it directly to the output buffer. It’s part of the filesystem extension in PHP.

Function signature:
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )

  • $filename: The path to the file you want to read.
  • $use_include_path: Optional boolean to search the file in the include_path.
  • $context: Optional context resource for file stream settings.

It returns the number of bytes read on success or false on failure.

Example 1: Basic Usage of readfile()

<?php
$file = 'example.txt';

if(readfile($file) === false) {
    echo "Failed to read the file.";
}
?>

This script will output the content of example.txt directly to the browser.

Example 2: Using readfile() for File Download Streaming

To serve a file as a download, you need to send appropriate HTTP headers before calling readfile():

<?php
$file = 'sample.pdf';

if(file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="' . basename($file) . '"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
} else {
    echo "File does not exist.";
}
?>

This example streams a PDF file to the user as a downloadable attachment using readfile().

Best Practices

  • Always validate the file path to avoid directory traversal attacks.
  • Check if the file exists before trying to read it with file_exists().
  • Send the correct HTTP headers before outputting file contents to control how the browser handles it.
  • Call exit immediately after readfile() when streaming files to prevent unwanted output.
  • Use filesize() function to send accurate Content-Length header.
  • For large files, consider output buffering management to optimize memory usage.

Common Mistakes

  • Not sending appropriate HTTP headers prior to calling readfile(), resulting in incorrect browser behavior.
  • Attempting to read files without checking file existence, causing warnings or errors.
  • Not escaping filenames properly when using them in headers, risking header injection vulnerabilities.
  • Calling readfile() with relative paths without understanding the current working directory.
  • Forgetting to terminate script execution after serving file with exit(), leading to corrupted downloads.

Interview Questions

Junior Level

  • What does the PHP readfile() function do?
    It reads a file and writes its contents directly to the output buffer.
  • What is the return value of readfile() on success?
    It returns the number of bytes read and written to output.
  • How do you check if the file exists before using readfile()?
    By using file_exists() function.
  • Can readfile() be used to serve a file download?
    Yes, by sending appropriate HTTP headers before calling readfile().
  • What happens if you call readfile() on a non-existing file?
    It returns false and may produce a warning unless suppressed.

Mid Level

  • Explain why it is important to send headers before calling readfile() for downloads.
    Headers control content type, disposition, and caching, instructing the browser how to handle the streamed file.
  • How would you prevent directory traversal attacks when using readfile()?
    By validating or sanitizing the file path, restricting access to allowed directories.
  • Why should you call exit; after readfile() when streaming files?
    To stop further script execution that could corrupt the file output.
  • Is readfile() memory efficient for reading large files?
    Yes, because it streams directly without loading entire file into memory.
  • What is the optional second parameter in readfile() used for?
    It specifies whether to search for the file in the include_path.

Senior Level

  • How can you use PHP stream contexts with readfile()?
    By passing a stream context resource to the third parameter to modify wrapper behavior, e.g., for headers or authentication.
  • Compare readfile() with using fopen(), fread() and output buffering for file streaming.
    readfile() is simpler and faster for direct output, but fopen() with buffering offers more control over read size and error handling.
  • What security considerations should be accounted for when serving files with readfile() in a production app?
    Sanitize inputs, validate file paths, restrict access permissions, and avoid exposing sensitive files.
  • How do you handle partial content requests (range requests) with readfile()?
    You must manually parse HTTP range headers and use fseek() to serve the requested byte range, as readfile() lacks built-in support.
  • What are potential pitfalls when using readfile() behind output buffering or compression layers?
    Output buffering can increase memory usage; compression might alter content length headers, causing mismatches and corrupted downloads.

Frequently Asked Questions (FAQ)

Can I use readfile() to read files other than text?
Yes, readfile() works with any file type because it outputs raw file data directly.
Is readfile() faster than file_get_contents() for outputting files?
Usually yes, because readfile() streams data directly to output without storing it fully in a variable first.
Why am I getting headers already sent errors when using readfile()?
This commonly happens if any output (even whitespace) is sent before headers. Make sure no output occurs before calling header() functions.
Can readfile() handle very large files in PHP?
Yes, because it streams file content directly without loading it entirely into RAM.
How do I force the browser to download a file instead of displaying it when using readfile()?
Send the Content-Disposition: attachment; filename="filename.ext" header before calling readfile().

Conclusion

The PHP readfile() function is an essential tool for efficiently reading and streaming files to users. Its direct-to-output approach makes it simple and memory-friendly for various file serving scenarios, especially downloads and media streaming. Ensuring proper headers, validating files, and following best practices will help you securely integrate readfile() in your PHP applications.

Whether you’re a beginner mastering file handling or an experienced developer optimizing file streaming, understanding readfile() is vital for seamless filesystem interactions in PHP.