How7o
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Reading: How to Get a Remote File’s Size from a URL in PHP
Share
How7oHow7o
Font ResizerAa
  • OS
Search
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Follow US
© 2024–2026 How7o. All rights reserved.
How7o > Free Laravel, PHP, WordPress & Server Tutorials > Web Development > How to Get a Remote File’s Size from a URL in PHP
Web Development

How to Get a Remote File’s Size from a URL in PHP

how7o
By how7o
Last updated: May 22, 2026
4 Min Read
Get a remote file size from URL in PHP with get_headers
SHARE

To get a remote file’s size from a URL in PHP without downloading the file, send a HEAD request and read the Content-Length response header. The simplest way is get_headers($url, true); the more robust way is cURL with CURLOPT_NOBODY.

Contents
  • Why filesize() doesn’t work
  • Quick — get_headers()
  • Robust — cURL with explicit HEAD
  • Formatting the size for display
  • Frequently asked questions
  • Related guides
  • References

Last verified: 2026-05-17 on PHP 8.3. Originally published 2023-02-22, rewritten and updated 2026-05-17.

Why filesize() doesn’t work

$url = 'https://example.com/file.mp4';
$filesize = filesize($url);
// Warning: filesize(): stat failed

filesize() calls stat(), which the PHP HTTP stream wrapper doesn’t implement. Use HTTP directly.

Quick — get_headers()

$url      = 'https://example.com/file.mp4';
$headers  = get_headers($url, true);
$filesize = isset($headers['Content-Length']) ? (int) $headers['Content-Length'] : 0;

echo "$filesize bytes";

Passing true as the second argument groups headers by name (case-insensitive). Content-Length is a string of digits — cast to int for arithmetic. If the server doesn’t send the header (chunked responses, dynamic endpoints), the lookup returns null and we fall back to 0.

PHP remote file size — get_headers, cURL HEAD with NOBODY, Content-Length parsing

Robust — cURL with explicit HEAD

function remoteFileSize(string $url): ?int {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY,         true);   // HEAD only
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);   // follow 301/302
    curl_setopt($ch, CURLOPT_TIMEOUT,        10);

    if (curl_exec($ch) === false) {
        curl_close($ch);
        return null;
    }

    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    curl_close($ch);

    return $size >= 0 ? (int) $size : null;
}

$bytes = remoteFileSize('https://example.com/file.mp4');
echo $bytes === null ? 'unknown' : "$bytes bytes";

The cURL version handles redirects, has an explicit timeout, and uses CURLINFO_CONTENT_LENGTH_DOWNLOAD which is already parsed from the header. Returns null when the server didn’t supply Content-Length — that’s the truthful answer, not 0.

Formatting the size for display

function humanBytes(int $bytes, int $decimals = 1): string {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $i = 0;
    while ($bytes >= 1024 && $i < count($units) - 1) {
        $bytes /= 1024;
        $i++;
    }
    return number_format($bytes, $decimals) . ' ' . $units[$i];
}

echo humanBytes(15728640); // "15.0 MB"

Frequently asked questions

Why doesn’t filesize() work on a URL?

filesize() calls stat() on the path, which only works for local filesystems (and stream wrappers that implement url_stat). The HTTP stream wrapper in PHP doesn’t implement it. get_headers() works because it issues an actual HTTP request (HEAD by default when $associative is true) and reads the Content-Length header from the response.

Does the server always send Content-Length?

No. Static files almost always do, but dynamic responses (PHP, Node, Python) often omit it because the size isn’t known until the body is generated — they use Transfer-Encoding: chunked instead. If Content-Length is missing, you cannot know the size without downloading the whole body. Handle that case explicitly in your code.

Should I use cURL instead of get_headers()?

cURL gives you finer control — explicit HEAD via CURLOPT_NOBODY, custom timeouts, header collection, and curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD) as a parsed shortcut. get_headers() is simpler and works in two lines. Pick cURL for production code that needs robust timeouts and error handling; get_headers() for scripts and one-off tools.

How does this compare to filesize() in terms of performance?

get_headers() still costs a network round-trip — typically 50–200 ms to a remote server, versus a microsecond for local filesize(). For a hot loop that needs many remote sizes, batch them: keep the cURL handle, reuse the TCP connection, or use curl_multi_* for parallel HEADs. Don’t call get_headers() in a tight loop without caching.

Related guides

  • How to Create a Folder If It Does Not Exist in PHP
  • How to Extract a .tar.gz Archive in PHP
  • How to Display PHP Errors

References

PHP get_headers(): php.net/manual/en/function.get-headers.php. PHP cURL CURLOPT_NOBODY: php.net/manual/en/function.curl-setopt.php. HTTP Content-Length: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length.

TAGGED:configurationhttpphp

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
[mc4wp_form]
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Copy Link Print
Previous Article Get the current year in PHP, Laravel and JavaScript How to Get the Current Year in PHP (and Laravel and JS)
Next Article Get the index in a jQuery each loop How to Get the Index in a jQuery .each() Loop
Leave a Comment

Leave a Reply Cancel reply

You must be logged in to post a comment.

FacebookLike
XFollow
PinterestPin
InstagramFollow
Most Popular
Set vi as the default editor in Ubuntu — a terminal opening the vim editor
How to Set vi (Vim) as the Default Editor in Ubuntu
June 8, 2026
rsync says ALL DONE but files are missing — a terminal showing ALL DONE next to an empty folder
rsync Says “ALL DONE” but Files Are Missing: How to Verify
June 8, 2026
Migrate a website to a new server with rsync — files copying from an old server to a new one over SSH
How to Migrate a Website to a New Server With rsync
June 8, 2026
Bun runtime — faster JS toolkit replacing npm in Laravel projects
How to Install Bun Runtime on Ubuntu (And Use It in a Laravel Project)
May 24, 2026
Tailscale mesh — peer-to-peer connections between devices, coordination server
How to Install Tailscale on Ubuntu (Zero-Config Mesh VPN for Self-Hosters)
May 24, 2026

You Might Also Like

Get a favicon URL with JavaScript
Web Development

How to Get a Website’s Favicon URL with JavaScript

4 Min Read
Laravel migration converting a MySQL column type from VARCHAR to DECIMAL without losing data
Web Development

How to Change a MySQL Column Type in Laravel Migration

6 Min Read
Laravel global variable for views — View::share in AppServiceProvider and View::composer wildcard patterns
Web Development

How to Set a Global Variable for Laravel Views

7 Min Read
Fix XAMPP MySQL shutdown unexpectedly error
Server Management

How to Fix “Error: MySQL Shutdown Unexpectedly” in XAMPP

5 Min Read
How7o

We provide tips, tricks, and advice for improving websites and doing better search.

Tools

  • Age Calculator
  • Word Counter
  • Image Upscaler
  • Password Generator
  • QR Code Generator
  • See all tools→

Pranks

  • Fake Blue Screen Prank
  • Hacker Typer
  • Fake iMessage Generator
  • Windows XP Crash Prank
  • Windows 11 Update Prank
  • See all prank screens →

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service
  • Sitemap
© 2024–2026 How7o. All rights reserved.
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?