Number::fileSize

Converts a byte count into a readable size string such as 1 KB or 2.5 MB.

Signature
Number::fileSize(int|float $bytes, int $precision = 0, ?int $maxPrecision = null): string
  • Added in Laravel 10.33.0

Parameters

ParameterTypeDescription
$$bytesint|floatThe size in bytes. Negative values are stepped down by magnitude and keep their sign.
$$precisionoptionalint= 0Exact fraction digits, padded with zeros.
$$maxPrecisionoptional?int= nullUpper bound on fraction digits. Takes priority over $precision.

Return value

stringThe size and its unit separated by a space, for example '1 KB' or '2.50 MB'.

Errors

Throws RuntimeException when the intl PHP extension is not loaded, because the number itself is rendered by Number::format().

Changelog

  • PHP 10.33.0Introduced together with the Illuminate\Support\Number class.
  • PHP 12.60.0Negative byte values now step through the units correctly instead of stopping at B.

Number::fileSize() walks the byte count down through B, KB, MB, GB, TB, PB, EB, ZB, YB, dividing by 1024 each step, and hands the remaining mantissa to Number::format(). Use it for upload limits, attachment sizes, cache and disk reports — anywhere a raw filesize() result would reach a human.

Binary steps, decimal labels

The divisor is 1024 but the units are written KB and MB, not KiB and MiB. That is the same convention most operating systems use, and it means the string will not agree with a disk vendor's marketing figure. If your audience needs strict IEC units you will have to build the string yourself.

The step threshold is 0.9, not 1

The loop advances while abs($bytes) / 1024 > 0.9, so anything from about 922 bytes upward is already promoted to KB. Number::fileSize(1000) returns 1 KB, not 1000 B. This keeps awkward strings like 1000 B off the screen but does mean the number you see can be below 1.

Despite doing the unit maths in plain PHP, this method still requires intl — the formatting call at the end is Number::format().

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Showing an attachment's size next to its download link
  • Rendering an upload limit in a validation error message
  • Summarising per-user disk consumption in an admin table

Frequently asked questions

Does Number::fileSize use 1000 or 1024 bytes per kilobyte?

1024, but it labels the result KB and MB rather than KiB and MiB. That matches most operating systems and file managers, and disagrees with drive manufacturers' decimal figures.

Why does 1000 bytes show as 1 KB instead of 1000 B?

The unit loop advances whenever the value divided by 1024 exceeds 0.9, so 922 bytes and above are already promoted to KB. With the default precision of 0, the resulting 0.98 rounds to 1.

Does Number::fileSize work without the intl extension?

No. It does the unit maths itself but formats the final number with Number::format(), which builds a NumberFormatter and throws RuntimeException when intl is missing.

More examples

Where each unit takes over

921 bytes still prints as 921 B but 922 flips to KB, because the loop advances at a ratio above 0.9 rather than 1.0. The maxPrecision column shows the underlying fraction — 0.9 KB — that the default precision of 0 rounds away to 1 KB.

Example · php
<?php

use Illuminate\Support\Number;

$sizes = [0, 512, 921, 922, 1024, 1048576, 1073741824, 1099511627776];

foreach ($sizes as $bytes) {
    printf("%-16s %-10s %s\n", $bytes, Number::fileSize($bytes), Number::fileSize($bytes, maxPrecision: 2));
}

Formatting an uploaded file

The raw byte count is kept in the payload for sorting and comparison while the formatted string is only for display. Never sort a table on the formatted value — '9 KB' and '10 MB' compare as strings in the wrong order.

Example · php
<?php

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Number;

class AttachmentController
{
    public function show(string $path): array
    {
        $bytes = Storage::disk('public')->size($path);

        return [
            'path' => $path,
            'bytes' => $bytes,
            'size' => Number::fileSize($bytes, maxPrecision: 1),
        ];
    }
}

Validation message with a limit

Prints 'The avatar may not be larger than 2 MB.' Deriving the message from the same constant as the rule keeps them from drifting apart, which is the usual reason an error message quotes a limit the validator does not actually enforce.

Example · php
<?php

use Illuminate\Support\Number;

$maxKilobytes = 2048; // Laravel's max: rule counts kilobytes
$limit = Number::fileSize($maxKilobytes * 1024);

$rules = ['avatar' => "required|image|max:{$maxKilobytes}"];
$messages = ['avatar.max' => "The avatar may not be larger than {$limit}."];

echo $messages['avatar.max'], PHP_EOL;

Discussion

  • Be the first to comment on this lesson.