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
Laravel Eloquent ORM — a model class mapping to a database table with query methods
Laravel Eloquent ORM: The Complete Guide to Querying Your Database
June 16, 2026
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

You Might Also Like

Laravel login and registration system with scaffolding packages
Web Development

How to Create a Login and Registration System in Laravel

5 Min Read
Upload files via Ajax with jQuery using FormData
Web Development

How to Upload Files via Ajax with jQuery

4 Min Read
Laravel delete file from public folder — File::delete with public_path
Web Development

How to Delete Files from the Public Folder in Laravel

7 Min Read
WooCommerce product view counter — meta-based counter with increment and display hooks
Web Development

How to Display a Product View Counter in WooCommerce Without a Plugin

7 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?